From f4b82535a7d801666f2a2f22d2c5099604a70df8 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Wed, 2 Sep 2020 20:44:37 -0700 Subject: [PATCH 1/7] MainScreenWithTabs: Use `router` static, pass `navigation` prop. This is the recommended thing to do when it's necessary to defy react-navigation's warnings [1] against "explicitly rendering more than one navigator". In the upcoming react-navigation v2 -> v3 upgrade, this would otherwise produce a crashing error; see discussion [2]. [1] https://reactnavigation.org/docs/2.x/common-mistakes/#explicitly-rendering-more-than-one-navigator [2] https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/Dynamic.20routes.20in.20react-navigation/near/1008268 --- src/main/MainScreenWithTabs.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/MainScreenWithTabs.js b/src/main/MainScreenWithTabs.js index fc6356124ac..e44598888f6 100644 --- a/src/main/MainScreenWithTabs.js +++ b/src/main/MainScreenWithTabs.js @@ -1,13 +1,20 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; import { View } from 'react-native'; +import type { NavigationScreenProp } from 'react-navigation'; import type { ThemeData } from '../styles'; import styles, { ThemeContext } from '../styles'; import { OfflineNotice, ZulipStatusBar } from '../common'; import MainTabs from './MainTabs'; -export default class MainScreenWithTabs extends PureComponent<{||}> { +type Props = $ReadOnly<{| + navigation: NavigationScreenProp<>, +|}>; + +export default class MainScreenWithTabs extends PureComponent { + static router = MainTabs.router; + static contextType = ThemeContext; context: ThemeData; @@ -16,7 +23,7 @@ export default class MainScreenWithTabs extends PureComponent<{||}> { - + ); } From 373e5e32c534ec702d13f7393905789b5eda9d39 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Thu, 3 Sep 2020 17:06:44 -0700 Subject: [PATCH 2/7] MessageReactionList [nfc]: Remove a prettier suppression. This has no effect. --- src/reactions/MessageReactionList.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/reactions/MessageReactionList.js b/src/reactions/MessageReactionList.js index a873f6e17cd..40007e826d4 100644 --- a/src/reactions/MessageReactionList.js +++ b/src/reactions/MessageReactionList.js @@ -62,7 +62,6 @@ const getReactionsTabs = ( ]), ); - // prettier-ignore return createMaterialTopTabNavigator(reactionsTabs, { backBehavior: 'none', From b080ef2dda8c54f16abda0751e93d505aaab4608 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Thu, 3 Sep 2020 14:23:38 -0700 Subject: [PATCH 3/7] MessageReactionList: Wrap rogue tab nav in `createNavigationContainer`. This will prevent a crashing error on iOS and Android that would otherwise be introduced in the upcoming react-navigation v2 -> v3 upgrade, on opening the message-reaction list. See discussion [1]. [1] https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/Dynamic.20routes.20in.20react-navigation/near/1008268 --- src/reactions/MessageReactionList.js | 43 ++++++++++++++++++---------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/src/reactions/MessageReactionList.js b/src/reactions/MessageReactionList.js index 40007e826d4..373696ce418 100644 --- a/src/reactions/MessageReactionList.js +++ b/src/reactions/MessageReactionList.js @@ -1,7 +1,7 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; import { View } from 'react-native'; -import { createMaterialTopTabNavigator } from 'react-navigation'; +import { createNavigationContainer, createMaterialTopTabNavigator } from 'react-navigation'; import type { NavigationScreenProp } from 'react-navigation'; import * as logging from '../utils/logging'; @@ -62,23 +62,32 @@ const getReactionsTabs = ( ]), ); - return createMaterialTopTabNavigator(reactionsTabs, { - backBehavior: 'none', + // It's not feasible to set up our newly created tab navigator as + // part of the entire app's navigation (see the note at + // `getReactionsTabs`'s call site). Given that, it seems we can use + // `createNavigationContainer` (soon to be called + // `createAppContainer`) so our violation of the "only explicitly + // render one navigator" rule doesn't become a crashing error in + // `react-navigation` v3. + return createNavigationContainer( + createMaterialTopTabNavigator(reactionsTabs, { + backBehavior: 'none', - // The user may have originally navigated here to look at a reaction - // that's since been removed. Ignore the nav hint in that case. - ...(reactionName !== undefined && reactionsTabs[reactionName] - ? { initialRouteName: reactionName } - : {}), + // The user may have originally navigated here to look at a reaction + // that's since been removed. Ignore the nav hint in that case. + ...(reactionName !== undefined && reactionsTabs[reactionName] + ? { initialRouteName: reactionName } + : {}), - ...tabsOptions({ - showLabel: true, - showIcon: false, - style: { - borderWidth: 0.15, - }, + ...tabsOptions({ + showLabel: true, + showIcon: false, + style: { + borderWidth: 0.15, + }, + }), }), - }); + ); }; type SelectorProps = $ReadOnly<{| @@ -135,6 +144,10 @@ class MessageReactionList extends PureComponent { ); } else { const aggregatedReactions = aggregateReactions(message.reactions, ownUserId); + // TODO: React Navigation doesn't want us to explicitly render + // more than one navigator in the app, and the recommended + // workaround isn't feasible; see discussion at + // https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/Dynamic.20routes.20in.20react-navigation/near/1008268. const TabView = getReactionsTabs(aggregatedReactions, reactionName, allUsersById); return ( From 99be838c250108c538adadc9ffe36a03b448adb0 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Wed, 2 Sep 2020 17:45:15 -0700 Subject: [PATCH 4/7] deps: Upgrade to react-navigation v3. In this commit: - Update react-navigation and its libdef, handle breaking changes in code - Update react-navigation-redux-helpers to keep compatibility; handle breaking changes and let it wrap AppNavigator in its preferred way - Add react-navigation-stack and react-navigation-drawer to prepare for the requirement in v4 that we depend on these directly. Match the versions of these (and that of react-navigation-tabs, which we're already depending on) to the versions react-navigation v3 has for these in its `dependencies` in its `package.json`. Grab a compatible libdef for react-navigation-stack. - Add @react-navigation/core, @react-navigation/native, and react-native-gesture-handler to satisfy peer dependencies. Follow instructions for some additional setup for react-native-gesture-handler in Jest config and `MainActivity.kt`. - Add a note about a console error that we're getting, which will go away in react-navigation v4. It doesn't seem to break any functionality. Also, run `yarn yarn-deduplicate && yarn` as prompted by `tools/test deps`. See more detail on GitHub at https://github.com/zulip/zulip-mobile/pull/4249#issuecomment-687342402. Fixes: #3649 --- .flowconfig | 6 +- .../main/java/com/zulipmobile/MainActivity.kt | 11 + .../npm/react-navigation-stack_v1.x.x.js | 951 ++++++++++++++++++ ...n_v2.x.x.js => react-navigation_v3.x.x.js} | 514 ++++++---- ios/Podfile.lock | 6 + jest.config.js | 2 +- package.json | 11 +- src/boot/store.js | 2 +- src/nav/AppNavigator.js | 3 - src/nav/AppWithNavigation.js | 4 +- src/reactions/MessageReactionList.js | 21 +- yarn.lock | 220 ++-- 12 files changed, 1413 insertions(+), 338 deletions(-) create mode 100644 flow-typed/npm/react-navigation-stack_v1.x.x.js rename flow-typed/npm/{react-navigation_v2.x.x.js => react-navigation_v3.x.x.js} (76%) diff --git a/.flowconfig b/.flowconfig index 06cca9ef76e..37d5fd4272f 100644 --- a/.flowconfig +++ b/.flowconfig @@ -28,7 +28,11 @@ node_modules/warning/.* .*/node_modules/react-native-notifications/.* .*/node_modules/react-native-tab-view/.* -.*/node_modules/react-navigation-redux-helpers/.* + +# Some mistakes in these types got fixed in v2.4.1 of this library, +# but we can't use that until we're on react-navigation v4 (#4248). +.*/node_modules/react-navigation-tabs/.* + .*/node_modules/react-native-safe-area/.* .*/node_modules/flow-coverage-report/.* .*/node_modules/@snyk/.* diff --git a/android/app/src/main/java/com/zulipmobile/MainActivity.kt b/android/app/src/main/java/com/zulipmobile/MainActivity.kt index 59e816965c1..3d3b2480617 100644 --- a/android/app/src/main/java/com/zulipmobile/MainActivity.kt +++ b/android/app/src/main/java/com/zulipmobile/MainActivity.kt @@ -6,9 +6,12 @@ import android.os.Bundle import android.util.Log import android.webkit.WebView import com.facebook.react.ReactActivity +import com.facebook.react.ReactActivityDelegate; +import com.facebook.react.ReactRootView; import com.facebook.react.ReactApplication import com.facebook.react.bridge.Arguments import com.facebook.react.bridge.WritableMap +import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView; import com.zulipmobile.notifications.* import com.zulipmobile.sharing.SharingModule @@ -23,6 +26,14 @@ open class MainActivity : ReactActivity() { return "ZulipMobile" } + override fun createReactActivityDelegate(): ReactActivityDelegate { + return object : ReactActivityDelegate(this, mainComponentName) { + override fun createRootView(): ReactRootView { + return RNGestureHandlerEnabledRootView(this@MainActivity) + } + } + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) WebView.setWebContentsDebuggingEnabled(true) diff --git a/flow-typed/npm/react-navigation-stack_v1.x.x.js b/flow-typed/npm/react-navigation-stack_v1.x.x.js new file mode 100644 index 00000000000..bcc11da514b --- /dev/null +++ b/flow-typed/npm/react-navigation-stack_v1.x.x.js @@ -0,0 +1,951 @@ +// flow-typed signature: c160a027e33cf97235b8234433c6420e +// flow-typed version: b527cb0ea1/react-navigation-stack_v1.x.x/flow_>=v0.104.x + +// @flow + +declare module 'react-navigation-stack' { + + //--------------------------------------------------------------------------- + // SECTION 1: IDENTICAL TYPE DEFINITIONS + // This section is identical across all React Navigation libdefs and contains + // shared definitions. We wish we could make it DRY and import from a shared + // definition, but that isn't yet possible. + //--------------------------------------------------------------------------- + + /** + * SECTION 1A + * We start with some definitions that we have copy-pasted from React Native + * source files. + */ + + // This is a bastardization of the true StyleObj type located in + // react-native/Libraries/StyleSheet/StyleSheetTypes. We unfortunately can't + // import that here, and it's too lengthy (and consequently too brittle) to + // copy-paste here either. + declare type StyleObj = + | null + | void + | number + | false + | '' + | $ReadOnlyArray + | { [name: string]: any, ... }; + declare type ViewStyleProp = StyleObj; + declare type TextStyleProp = StyleObj; + declare type AnimatedViewStyleProp = StyleObj; + declare type AnimatedTextStyleProp = StyleObj; + + /** + * SECTION 1B + * The following are type declarations for core types necessary for every + * React Navigation libdef. + */ + + /** + * Navigation State + Action + */ + + declare export type NavigationParams = { [key: string]: mixed, ... }; + + declare export type NavigationBackAction = {| + type: 'Navigation/BACK', + key?: ?string, + |}; + declare export type NavigationInitAction = {| + type: 'Navigation/INIT', + params?: NavigationParams, + |}; + declare export type NavigationNavigateAction = {| + type: 'Navigation/NAVIGATE', + routeName: string, + params?: NavigationParams, + + // The action to run inside the sub-router + action?: NavigationNavigateAction, + + key?: string, + |}; + declare export type NavigationSetParamsAction = {| + type: 'Navigation/SET_PARAMS', + + // The key of the route where the params should be set + key: string, + + // The new params to merge into the existing route params + params: NavigationParams, + |}; + + declare export type NavigationPopAction = {| + +type: 'Navigation/POP', + +n?: number, + +immediate?: boolean, + |}; + declare export type NavigationPopToTopAction = {| + +type: 'Navigation/POP_TO_TOP', + +immediate?: boolean, + |}; + declare export type NavigationPushAction = {| + +type: 'Navigation/PUSH', + +routeName: string, + +params?: NavigationParams, + +action?: NavigationNavigateAction, + +key?: string, + |}; + declare export type NavigationResetAction = {| + type: 'Navigation/RESET', + index: number, + key?: ?string, + actions: Array, + |}; + declare export type NavigationReplaceAction = {| + +type: 'Navigation/REPLACE', + +key: string, + +routeName: string, + +params?: NavigationParams, + +action?: NavigationNavigateAction, + |}; + declare export type NavigationCompleteTransitionAction = {| + +type: 'Navigation/COMPLETE_TRANSITION', + +key?: string, + +toChildKey?: string, + |}; + + declare export type NavigationOpenDrawerAction = {| + +type: 'Navigation/OPEN_DRAWER', + +key?: string, + |}; + declare export type NavigationCloseDrawerAction = {| + +type: 'Navigation/CLOSE_DRAWER', + +key?: string, + |}; + declare export type NavigationToggleDrawerAction = {| + +type: 'Navigation/TOGGLE_DRAWER', + +key?: string, + |}; + declare export type NavigationDrawerOpenedAction = {| + +type: 'Navigation/DRAWER_OPENED', + +key?: string, + |}; + declare export type NavigationDrawerClosedAction = {| + +type: 'Navigation/DRAWER_CLOSED', + +key?: string, + |}; + + declare export type NavigationJumpToAction = {| + +type: 'Navigation/JUMP_TO'; + +preserveFocus: boolean, + +routeName: string, + +key?: string, + +params?: NavigationParams, + |}; + + declare export type NavigationAction = + | NavigationBackAction + | NavigationInitAction + | NavigationNavigateAction + | NavigationSetParamsAction + | NavigationPopAction + | NavigationPopToTopAction + | NavigationPushAction + | NavigationResetAction + | NavigationReplaceAction + | NavigationCompleteTransitionAction + | NavigationOpenDrawerAction + | NavigationCloseDrawerAction + | NavigationToggleDrawerAction + | NavigationDrawerOpenedAction + | NavigationDrawerClosedAction + | NavigationJumpToAction; + + /** + * NavigationState is a tree of routes for a single navigator, where each + * child route may either be a NavigationScreenRoute or a + * NavigationRouterRoute. NavigationScreenRoute represents a leaf screen, + * while the NavigationRouterRoute represents the state of a child navigator. + * + * NOTE: NavigationState is a state tree local to a single navigator and + * its child navigators (via the routes field). + * If we're in navigator nested deep inside the app, the state will only be + * the state for that navigator. + * The state for the root navigator of our app represents the whole navigation + * state for the whole app. + */ + declare export type NavigationState = { + /** + * Index refers to the active child route in the routes array. + */ + index: number, + routes: Array, + isTransitioning?: bool, + ... + }; + + declare export type NavigationRoute = + | NavigationLeafRoute + | NavigationStateRoute; + + declare export type NavigationLeafRoute = {| + /** + * React's key used by some navigators. No need to specify these manually, + * they will be defined by the router. + */ + key: string, + /** + * For example 'Home'. + * This is used as a key in a route config when creating a navigator. + */ + routeName: string, + /** + * Path is an advanced feature used for deep linking and on the web. + */ + path?: string, + /** + * Params passed to this route when navigating to it, + * e.g. `{ car_id: 123 }` in a route that displays a car. + */ + params?: NavigationParams, + |}; + + declare export type NavigationStateRoute = {| + ...NavigationLeafRoute, + ...$Exact, + |}; + + /** + * Router + */ + + declare export type NavigationScreenProps = { [key: string]: mixed, ... }; + + declare export type NavigationScreenOptionsGetter = ( + navigation: NavigationScreenProp, + screenProps: ?NavigationScreenProps, + theme: SupportedThemes, + ) => Options; + + declare export type NavigationRouter = { + /** + * The reducer that outputs the new navigation state for a given action, + * with an optional previous state. When the action is considered handled + * but the state is unchanged, the output state is null. + */ + getStateForAction: (action: NavigationAction, lastState: ?State) => ?State, + /** + * Maps a URI-like string to an action. This can be mapped to a state + * using `getStateForAction`. + */ + getActionForPathAndParams: ( + path: string, + params?: NavigationParams + ) => ?NavigationAction, + getPathAndParamsForState: ( + state: State + ) => { + path: string, + params?: NavigationParams, + ... + }, + getComponentForRouteName: (routeName: string) => NavigationComponent, + getComponentForState: (state: State) => NavigationComponent, + /** + * Gets the screen navigation options for a given screen. + * + * For example, we could get the config for the 'Foo' screen when the + * `navigation.state` is: + * + * {routeName: 'Foo', key: '123'} + */ + getScreenOptions: NavigationScreenOptionsGetter, + ... + }; + + declare export type NavigationScreenOptions = { title?: string, ... }; + + declare export type SupportedThemes = 'light' | 'dark'; + + declare export type NavigationScreenConfigProps = $Shape<{| + navigation: NavigationScreenProp, + screenProps: NavigationScreenProps, + theme: SupportedThemes, + |}>; + + declare export type NavigationScreenConfig = + | Options + | (({| + ...NavigationScreenConfigProps, + navigationOptions: Options, + |}) => Options); + + declare export type NavigationComponent = + | NavigationScreenComponent + | NavigationNavigator<*, *, *>; + + declare interface withOptionalNavigationOptions { + navigationOptions?: NavigationScreenConfig; + } + + declare export type NavigationScreenComponent< + Route: NavigationRoute, + Options: {...}, + Props: NavigationNavigatorProps, + > = React$ComponentType & + withOptionalNavigationOptions; + + declare interface withRouter { + router: NavigationRouter; + } + + declare export type NavigationNavigator< + State: NavigationState, + Options: {...}, + Props: NavigationNavigatorProps, + > = React$ComponentType & + withRouter & + withOptionalNavigationOptions; + + declare type _NavigationRouteConfigCore = {| + navigationOptions?: NavigationScreenConfig<*>, + params?: NavigationParams, + path?: string, + |}; + declare export type NavigationRouteConfig = + | NavigationComponent + | {| ..._NavigationRouteConfigCore, screen: NavigationComponent |} + | {| ..._NavigationRouteConfigCore, getScreen: () => NavigationComponent |}; + + declare export type NavigationRouteConfigMap = { [routeName: string]: NavigationRouteConfig, ... }; + + /** + * Navigator Prop + */ + + declare export type NavigationDispatch = ( + action: NavigationAction + ) => boolean; + + declare export type EventType = + | 'willFocus' + | 'didFocus' + | 'willBlur' + | 'didBlur' + | 'action'; + + declare export type NavigationEventPayload = {| + type: EventType, + action: NavigationAction, + state: NavigationState, + lastState: ?NavigationState, + |}; + + declare export type NavigationEventCallback = ( + payload: NavigationEventPayload + ) => void; + + declare export type NavigationEventSubscription = {| remove: () => void |}; + + declare export type NavigationScreenProp<+S> = { + +state: S, + dispatch: NavigationDispatch, + addListener: ( + eventName: string, + callback: NavigationEventCallback + ) => NavigationEventSubscription, + getParam: ( + paramName: ParamName, + fallback?: $ElementType< + $PropertyType< + {| + ...{| params: {...} |}, + ...$Exact, + |}, + 'params' + >, + ParamName + > + ) => $ElementType< + $PropertyType< + {| + ...{| params: {...} |}, + ...$Exact, + |}, + 'params' + >, + ParamName + >, + dangerouslyGetParent: () => ?NavigationScreenProp, + isFocused: () => boolean, + goBack: (routeKey?: ?string) => boolean, + dismiss: () => boolean, + navigate: ( + routeName: + | string + | { + routeName: string, + params?: NavigationParams, + action?: NavigationNavigateAction, + key?: string, + ... + }, + params?: NavigationParams, + action?: NavigationNavigateAction + ) => boolean, + setParams: (newParams: NavigationParams) => boolean, + ... + }; + + declare export type NavigationNavigatorProps = $Shape<{ + navigation: NavigationScreenProp, + screenProps?: NavigationScreenProps, + navigationOptions?: O, + theme?: SupportedThemes | 'no-preference', + detached?: boolean, + ... + }>; + + /** + * Navigation container + */ + + declare export type NavigationContainer< + State: NavigationState, + Options: {...}, + Props: NavigationContainerProps, + > = React$ComponentType & + withRouter & + withOptionalNavigationOptions; + + declare export type NavigationContainerProps = $Shape<{ + uriPrefix?: string | RegExp, + onNavigationStateChange?: ?( + NavigationState, + NavigationState, + NavigationAction + ) => void, + navigation?: NavigationScreenProp, + persistenceKey?: ?string, + renderLoadingExperimental?: React$ComponentType<{...}>, + screenProps?: NavigationScreenProps, + navigationOptions?: O, + ... + }>; + + /** + * NavigationDescriptor + */ + + declare export type NavigationDescriptor = { + key: string, + state: NavigationRoute, + navigation: NavigationScreenProp, + getComponent: () => NavigationComponent, + ... + }; + + declare export type NavigationDescriptorMap = { + [key: string]: NavigationDescriptor, + ... + }; + + //--------------------------------------------------------------------------- + // SECTION 2: SHARED TYPE DEFINITIONS + // This section too is copy-pasted, but it's not identical across all React + // Navigation libdefs. We pick out bits and pieces that we need. + //--------------------------------------------------------------------------- + + /** + * SECTION 2A + * We start with definitions we have copy-pasted, either from in-package + * types, other Flow libdefs, or from TypeScript types somewhere. + */ + + // This is copied from + // react-native/Libraries/Animated/src/nodes/AnimatedInterpolation.js + declare type ExtrapolateType = 'extend' | 'identity' | 'clamp'; + declare type InterpolationConfigType = { + inputRange: Array, + outputRange: Array | Array, + easing?: (input: number) => number, + extrapolate?: ExtrapolateType, + extrapolateLeft?: ExtrapolateType, + extrapolateRight?: ExtrapolateType, + ... + }; + declare class AnimatedInterpolation { + interpolate(config: InterpolationConfigType): AnimatedInterpolation; + } + + // This is copied from + // react-native/Libraries/Animated/src/animations/Animation.js + declare type EndResult = { finished: boolean, ... }; + declare type EndCallback = (result: EndResult) => void; + declare class Animation { + start( + fromValue: number, + onUpdate: (value: number) => void, + onEnd: ?EndCallback, + previousAnimation: ?Animation, + animatedValue: AnimatedValue, + ): void; + stop(): void; + } + + // This is vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedTracking.js + declare class AnimatedTracking { + constructor( + value: AnimatedValue, + parent: any, + animationClass: any, + animationConfig: Object, + callback?: ?EndCallback, + ): void; + update(): void; + } + + // This is vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedValue.js + declare type ValueListenerCallback = (state: { value: number, ... }) => void; + declare class AnimatedValue { + constructor(value: number): void; + setValue(value: number): void; + setOffset(offset: number): void; + flattenOffset(): void; + extractOffset(): void; + addListener(callback: ValueListenerCallback): string; + removeListener(id: string): void; + removeAllListeners(): void; + stopAnimation(callback?: ?(value: number) => void): void; + resetAnimation(callback?: ?(value: number) => void): void; + interpolate(config: InterpolationConfigType): AnimatedInterpolation; + animate(animation: Animation, callback: ?EndCallback): void; + stopTracking(): void; + track(tracking: AnimatedTracking): void; + } + + /** + * SECTION 2B + * The following are the actually useful definitions in Section 2, that are + * used below in section 3, but also in other libdefs. + */ + + declare export type NavigationPathsConfig = { [routeName: string]: string, ... }; + + /** + * SafeAreaView + */ + + declare type _SafeAreaViewForceInsetValue = 'always' | 'never' | number; + declare type _SafeAreaViewInsets = $Shape<{| + top: _SafeAreaViewForceInsetValue, + bottom: _SafeAreaViewForceInsetValue, + left: _SafeAreaViewForceInsetValue, + right: _SafeAreaViewForceInsetValue, + vertical: _SafeAreaViewForceInsetValue, + horizontal: _SafeAreaViewForceInsetValue, + |}>; + + /** + * Interpolation + */ + + declare export type NavigationStackInterpolatorProps = $Shape<{| + layout: NavigationStackLayout, + scene: NavigationStackScene, + scenes: NavigationStackScene[], + position: AnimatedInterpolation, + navigation: NavigationStackProp, + mode?: HeaderMode, + shadowEnabled?: boolean, + cardOverlayEnabled?: boolean, + |}>; + + declare type _InterpolationResult = { [key: string]: mixed, ... }; + declare export type NavigationStackInterpolator = + (props: NavigationStackInterpolatorProps) => _InterpolationResult; + + /** + * Header + */ + + declare export type HeaderMode = 'float' | 'screen' | 'none'; + + declare export type HeaderProps = {| + layout: NavigationStackLayout, + scene: NavigationStackScene, + scenes: NavigationStackScene[], + position: AnimatedInterpolation, + navigation: NavigationStackProp, + mode: HeaderMode, + leftInterpolator?: NavigationStackInterpolator, + titleInterpolator?: NavigationStackInterpolator, + rightInterpolator?: NavigationStackInterpolator, + backgroundInterpolator?: NavigationStackInterpolator, + layoutPreset: 'left' | 'center', + transitionPreset?: 'fade-in-place' | 'uikit', + backTitleVisible?: boolean, + isLandscape: boolean, + |}; + + /** + * StackRouter + */ + + declare export type NavigationStackProp<+S> = + & NavigationScreenProp + & { + pop: (n?: number, params?: {| immediate?: boolean |}) => boolean, + popToTop: (params?: {| immediate?: boolean |}) => boolean, + push: ( + routeName: string, + params?: NavigationParams, + action?: NavigationNavigateAction + ) => boolean, + replace: ( + routeName: string, + params?: NavigationParams, + action?: NavigationNavigateAction + ) => boolean, + reset: (actions: NavigationAction[], index: number) => boolean, + ... + }; + + declare type _HeaderBackButtonProps = {| + disabled?: boolean, + onPress: () => void, + pressColorAndroid?: string, + tintColor?: ?string, + backImage?: React$ComponentType<{ + tintColor: string, + title?: ?string, + ... + }>, + title?: ?string, + truncatedTitle?: ?string, + backTitleVisible?: boolean, + allowFontScaling?: boolean, + titleStyle?: ?TextStyleProp, + width?: ?number, + |}; + + declare export type NavigationStackScreenOptions = NavigationScreenOptions & { + header?: ?(React$Node | (HeaderProps => React$Node)), + headerTransparent?: boolean, + headerTitle?: (props: { children: ?string, ... }) => React$Node | React$Node, + headerTitleStyle?: AnimatedTextStyleProp, + headerTitleAllowFontScaling?: boolean, + headerTintColor?: string, + headerLeft?: ((props: _HeaderBackButtonProps) => React$Node) | React$Node, + headerBackTitle?: ?string, + headerBackImage?: (props: {| + tintColor?: string, + title?: ?string, + |}) => React$Node, + headerTruncatedBackTitle?: string, + headerBackTitleStyle?: TextStyleProp, + headerPressColorAndroid?: string, + headerRight?: React$Node, + headerStyle?: ViewStyleProp, + headerForceInset?: _SafeAreaViewInsets, + headerBackground?: React$Node | React$ElementType, + gesturesEnabled?: boolean, + gestureResponseDistance?: {| + vertical?: number, + horizontal?: number, + |}, + gestureDirection?: 'default' | 'inverted', + ... + }; + + declare export type NavigationStackRouterConfig = {| + initialRouteName?: string, + initialRouteParams?: NavigationParams, + paths?: NavigationPathsConfig, + navigationOptions?: NavigationScreenConfig<*>, + defaultNavigationOptions?: NavigationScreenConfig<*>, + initialRouteKey?: string, + |}; + + /** + * Stack Gestures, Animations, and Interpolators + */ + + declare export type NavigationStackLayout = { + height: AnimatedValue, + initHeight: number, + initWidth: number, + isMeasured: boolean, + width: AnimatedValue, + ... + }; + + declare export type NavigationStackScene = { + index: number, + isActive: boolean, + isStale: boolean, + key: string, + route: NavigationRoute, + descriptor: ?NavigationDescriptor, + ... + }; + + //--------------------------------------------------------------------------- + // SECTION 3: UNIQUE TYPE DEFINITIONS + // This section contains exported types that are not present in any other + // React Navigation libdef. + //--------------------------------------------------------------------------- + + /** + * NavigationStackTransitionProps + */ + + declare export type NavigationStackTransitionProps = $Shape<{| + // The layout of the screen container + layout: NavigationStackLayout, + // The destination navigation state of the transition + navigation: NavigationStackProp, + // The progressive index of the transitioner's navigation state. + position: AnimatedValue, + // All the scenes of the transitioner. + scenes: Array, + // The active scene, corresponding to the route at + // `navigation.state.routes[navigation.state.index]`. When rendering + // NavigationSceneRendererPropsIndex, the scene does not refer to the active + // scene, but instead the scene that is being rendered. The index always + // is the index of the scene + scene: NavigationStackScene, + index: number, + |}>; + + + /** + * StackNavigator + */ + + declare type _NavigationTransitionConfigurer = ( + transitionProps: NavigationStackTransitionProps, + prevTransitionProps: ?NavigationStackTransitionProps, + isModal: boolean + ) => TransitionConfig; + + declare export type NavigationStackViewConfig = {| + mode?: 'card' | 'modal', + headerMode?: HeaderMode, + headerLayoutPreset?: 'left' | 'center', + headerTransitionPreset?: 'fade-in-place' | 'uikit', + headerBackgroundTransitionPreset?: 'translate' | 'fade' | 'toggle', + headerBackTitleVisible?: boolean, + disableKeyboardHandling?: boolean, + cardShadowEnabled?: boolean, + cardOverlayEnabled?: boolean, + onTransitionStart?: ( + transitionProps: NavigationStackTransitionProps, + prevTransitionProps: ?NavigationStackTransitionProps, + ) => void, + onTransitionEnd?: ( + transitionProps: NavigationStackTransitionProps, + prevTransitionProps: ?NavigationStackTransitionProps, + ) => void, + cardStyle?: ViewStyleProp, + transitionConfig?: _NavigationTransitionConfigurer, + transparentCard?: boolean, + |}; + + declare export type StackNavigatorConfig = $Shape<{| + ...NavigationStackViewConfig, + ...NavigationStackRouterConfig, + |}>; + + /** + * Transitioner + */ + + declare export type NavigationTransitionSpec = { + // A timing function such as `Animated.timing`. + timing: (value: AnimatedValue, config: any) => any, + duration?: number, + // An easing function from `Easing`. + easing?: (t: number) => number, + ... + }; + + // Describes a visual transition from one screen to another. + declare export type TransitionConfig = {| + // The basics properties of the animation, such as duration and easing + transitionSpec: NavigationTransitionSpec, + // How to animate position and opacity of the screen + // based on the value generated by the transitionSpec + screenInterpolator: NavigationStackInterpolator, + // How to animate position and opacity of the header components + // based on the value generated by the transitionSpec + headerLeftInterpolator?: NavigationStackInterpolator, + headerLeftLabelInterpolator?: NavigationStackInterpolator, + headerLeftButtonInterpolator?: NavigationStackInterpolator, + headerTitleFromLeftInterpolator?: NavigationStackInterpolator, + headerTitleInterpolator?: NavigationStackInterpolator, + headerRightInterpolator?: NavigationStackInterpolator, + headerBackgroundInterpolator?: NavigationStackInterpolator, + headerLayoutInterpolator?: NavigationStackInterpolator, + // The style of the container. Useful when a scene doesn't have + // 100% opacity and the underlying container is visible. + containerStyle?: ViewStyleProp, + containerStyleLight?: ViewStyleProp, + containerStyleDark?: ViewStyleProp, + |}; + + //--------------------------------------------------------------------------- + // SECTION 4: EXPORTED MODULE + // This is the only section that types exports. Other sections export types, + // but this section types the module's exports. + //--------------------------------------------------------------------------- + + declare export function createStackNavigator( + routeConfigMap: NavigationRouteConfigMap, + stackConfig?: StackNavigatorConfig + ): NavigationNavigator<*, *, *>; + + declare export var Header: React$ComponentType & { HEIGHT: number, ... }; + + declare export var HeaderBackButton: React$ComponentType< + _HeaderBackButtonProps + >; + + declare type _HeaderTitleProps = {| + children: React$Node, + style?: AnimatedTextStyleProp, + |}; + declare export var HeaderTitle: React$ComponentType<_HeaderTitleProps>; + + declare export var HeaderStyleInterpolator: {| + forLayout: NavigationStackInterpolator, + forLeft: NavigationStackInterpolator, + forLeftButton: NavigationStackInterpolator, + forLeftLabel: NavigationStackInterpolator, + forCenterFromLeft: NavigationStackInterpolator, + forCenter: NavigationStackInterpolator, + forRight: NavigationStackInterpolator, + forBackground: NavigationStackInterpolator, + forBackgroundWithInactiveHidden: NavigationStackInterpolator, + forBackgroundWithFade: NavigationStackInterpolator, + forBackgroundWithTranslation: NavigationStackInterpolator, + |}; + + declare type _StackViewProps = {| + navigation: NavigationStackProp, + descriptors: NavigationDescriptorMap, + navigationConfig: NavigationStackViewConfig, + onTransitionStart?: ( + transitionProps: NavigationStackTransitionProps, + prevTransitionProps: ?NavigationStackTransitionProps + ) => void, + onGestureBegin?: () => void, + onGestureCanceled?: () => void, + onGestureEnd?: () => void, + screenProps?: NavigationScreenProps, + |}; + declare export var StackView: React$ComponentType<_StackViewProps>; + + declare type _StackViewCardProps = {| + ...$Exact<_PointerEventsInputProps>, + style: ViewStyleProp, + animatedStyle: any, + position: AnimatedInterpolation, + transparent?: boolean, + children: React$Node, + |}; + declare export var StackViewCard: React$ComponentType<_StackViewCardProps>; + + declare type _StackViewLayoutProps = {| + mode?: 'card' | 'modal', + headerMode?: HeaderMode, + headerLayoutPreset?: 'left' | 'center', + headerTransitionPreset?: 'fade-in-place' | 'uikit', + headerBackgroundTransitionPreset?: 'translate' | 'fade' | 'toggle', + headerBackTitleVisible?: boolean, + shadowEnabled?: boolean, + cardStyle?: ViewStyleProp, + transitionConfig?: _NavigationTransitionConfigurer, + transparentCard?: boolean, + transitionProps: NavigationStackTransitionProps, + lastTransitionProps: ?NavigationStackTransitionProps, + onGestureBegin?: () => void, + onGestureEnd?: () => void, + onGestureCanceled?: () => void, + screenProps?: NavigationScreenProps, + |}; + declare export var StackViewLayout: React$ComponentType<_StackViewLayoutProps>; + + declare export var StackViewStyleInterpolator: {| + forHorizontal: NavigationStackInterpolator, + forVertical: NavigationStackInterpolator, + forFadeFromBottomAndroid: NavigationStackInterpolator, + forFadeToBottomAndroid: NavigationStackInterpolator, + forFade: NavigationStackInterpolator, + forNoAnimation: NavigationStackInterpolator, + |}; + + declare export var StackViewTransitionConfigs: {| + defaultTransitionConfig: _NavigationTransitionConfigurer, + getTransitionConfig: ( + transitionConfigurer: ?_NavigationTransitionConfigurer, + transitionProps: NavigationStackTransitionProps, + prevTransitionProps: ?NavigationStackTransitionProps, + isModal: boolean + ) => TransitionConfig, + SlideFromRightIOS: TransitionConfig, + ModalSlideFromBottomIOS: TransitionConfig, + FadeInFromBottomAndroid: TransitionConfig, + FadeOutToBottomAndroid: TransitionConfig, + NoAnimation: TransitionConfig, + |}; + + declare type _PointerEventsInputProps = { + scene: NavigationStackScene, + navigation: NavigationStackProp, + realPosition: AnimatedValue, + ... + }; + declare type _PointerEventsInjectedProps = { + pointerEvents: 'box-only' | 'none' | 'auto', + onComponentRef: (ref: any) => void, + ... + }; + declare export function createPointerEventsContainer< + Props: _PointerEventsInputProps & _PointerEventsInjectedProps, + ComponentType: React$ComponentType, + >( + Component: ComponentType + ): React$ComponentType<$Diff, _PointerEventsInjectedProps>>; + + declare type _TransitionerProps = {| + render: ( + transitionProps: NavigationStackTransitionProps, + prevTransitionProps: ?NavigationStackTransitionProps + ) => React$Node, + configureTransition?: ( + transitionProps: NavigationStackTransitionProps, + prevTransitionProps: ?NavigationStackTransitionProps + ) => NavigationTransitionSpec, + onTransitionStart?: ( + transitionProps: NavigationStackTransitionProps, + prevTransitionProps: ?NavigationStackTransitionProps + ) => void, + onTransitionEnd?: ( + transitionProps: NavigationStackTransitionProps, + prevTransitionProps: ?NavigationStackTransitionProps + ) => void, + navigation: NavigationStackProp, + descriptors: NavigationDescriptorMap, + screenProps?: NavigationScreenProps, + |}; + declare export var Transitioner: React$ComponentType<_TransitionerProps>; + + declare export function ScenesReducer( + scenes: $ReadOnlyArray, + nextState: NavigationState, + prevState: ?NavigationState, + descriptors: NavigationDescriptorMap + ): NavigationStackScene[]; + + declare export var StackGestureContext: React$Context>; + +} diff --git a/flow-typed/npm/react-navigation_v2.x.x.js b/flow-typed/npm/react-navigation_v3.x.x.js similarity index 76% rename from flow-typed/npm/react-navigation_v2.x.x.js rename to flow-typed/npm/react-navigation_v3.x.x.js index 4c2319c02a1..a149eed9c32 100644 --- a/flow-typed/npm/react-navigation_v2.x.x.js +++ b/flow-typed/npm/react-navigation_v3.x.x.js @@ -1,5 +1,5 @@ -// flow-typed signature: 5b7de89063ce9294c5f60398863859ff -// flow-typed version: 16cbaddecd/react-navigation_v2.x.x/flow_>=v0.60.x <=v0.103.x +// flow-typed signature: c42f0cec370b12d98c16672216f01404 +// flow-typed version: 036cb66b1b/react-navigation_v3.x.x/flow_>=v0.104.x // @flow @@ -20,7 +20,7 @@ declare module 'react-navigation' { | false | '' | $ReadOnlyArray - | { [name: string]: any }; + | { [name: string]: any, ... }; declare type ViewStyleProp = StyleObj; declare type TextStyleProp = StyleObj; declare type AnimatedViewStyleProp = StyleObj; @@ -31,6 +31,7 @@ declare module 'react-navigation' { declare type TabViewLayout = { height: number, width: number, + ... }; // This is copied from react-native/Libraries/Image/ImageSource.js @@ -44,21 +45,73 @@ declare module 'react-navigation' { width?: number, height?: number, scale?: number, + ... }; declare type ImageSource = ImageURISource | number | Array; - // This one is too large to copy. Actual definition is in - // react-native/Libraries/Animated/src/nodes/AnimatedValue.js - declare type AnimatedValue = Object; - - declare type HeaderForceInset = { - horizontal?: string, - vertical?: string, - left?: string, - right?: string, - top?: string, - bottom?: string, + // This is copied from + // react-native/Libraries/Animated/src/nodes/AnimatedInterpolation.js + declare type ExtrapolateType = 'extend' | 'identity' | 'clamp'; + declare type InterpolationConfigType = { + inputRange: Array, + outputRange: Array | Array, + easing?: (input: number) => number, + extrapolate?: ExtrapolateType, + extrapolateLeft?: ExtrapolateType, + extrapolateRight?: ExtrapolateType, + ... }; + declare class AnimatedInterpolation { + interpolate(config: InterpolationConfigType): AnimatedInterpolation; + } + + // This is copied from + // react-native/Libraries/Animated/src/animations/Animation.js + declare type EndResult = { finished: boolean, ... }; + declare type EndCallback = (result: EndResult) => void; + declare class Animation { + start( + fromValue: number, + onUpdate: (value: number) => void, + onEnd: ?EndCallback, + previousAnimation: ?Animation, + animatedValue: AnimatedValue, + ): void; + stop(): void; + } + + // This is vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedTracking.js + declare class AnimatedTracking { + constructor( + value: AnimatedValue, + parent: any, + animationClass: any, + animationConfig: Object, + callback?: ?EndCallback, + ): void; + update(): void; + } + + // This is vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedValue.js + declare type ValueListenerCallback = (state: { value: number, ... }) => void; + declare class AnimatedValue { + constructor(value: number): void; + setValue(value: number): void; + setOffset(offset: number): void; + flattenOffset(): void; + extractOffset(): void; + addListener(callback: ValueListenerCallback): string; + removeListener(id: string): void; + removeAllListeners(): void; + stopAnimation(callback?: ?(value: number) => void): void; + resetAnimation(callback?: ?(value: number) => void): void; + interpolate(config: InterpolationConfigType): AnimatedInterpolation; + animate(animation: Animation, callback: ?EndCallback): void; + stopTracking(): void; + track(tracking: AnimatedTracking): void; + } /** * Next, all the type declarations @@ -68,9 +121,7 @@ declare module 'react-navigation' { * Navigation State + Action */ - declare export type NavigationParams = { - [key: string]: mixed, - }; + declare export type NavigationParams = { [key: string]: mixed, ... }; declare export type NavigationBackAction = {| type: 'Navigation/BACK', @@ -191,6 +242,8 @@ declare module 'react-navigation' { */ index: number, routes: Array, + isTransitioning?: bool, + ... }; declare export type NavigationRoute = @@ -228,19 +281,18 @@ declare module 'react-navigation' { * Router */ - declare export type NavigationScreenOptionsGetter = ( + declare export type NavigationScreenOptionsGetter = ( navigation: NavigationScreenProp, - screenProps?: {} + screenProps?: {...} ) => Options; - declare export type NavigationRouter = { + declare export type NavigationRouter = { /** * The reducer that outputs the new navigation state for a given action, * with an optional previous state. When the action is considered handled * but the state is unchanged, the output state is null. */ getStateForAction: (action: NavigationAction, lastState: ?State) => ?State, - /** * Maps a URI-like string to an action. This can be mapped to a state * using `getStateForAction`. @@ -249,18 +301,15 @@ declare module 'react-navigation' { path: string, params?: NavigationParams ) => ?NavigationAction, - getPathAndParamsForState: ( state: State ) => { path: string, params?: NavigationParams, + ... }, - getComponentForRouteName: (routeName: string) => NavigationComponent, - getComponentForState: (state: State) => NavigationComponent, - /** * Gets the screen navigation options for a given screen. * @@ -270,33 +319,35 @@ declare module 'react-navigation' { * {routeName: 'Foo', key: '123'} */ getScreenOptions: NavigationScreenOptionsGetter, + ... }; declare export type NavigationScreenDetails = { options: T, state: NavigationRoute, navigation: NavigationScreenProp, + ... }; - declare export type NavigationScreenOptions = { - title?: string, - }; + declare export type NavigationScreenOptions = { title?: string, ... }; declare export type NavigationScreenConfigProps = $Shape<{ navigation: NavigationScreenProp, - screenProps: {}, + screenProps: {...}, + ... }>; declare export type NavigationScreenConfig = | Options | (({ - ...$Exact, - navigationOptions: Options, - }) => Options); + ...$Exact, + navigationOptions: Options, + ... + }) => Options); declare export type NavigationComponent = | NavigationScreenComponent - | NavigationContainer<*, *, *>; + | NavigationNavigator<*, *, *>; declare interface withOptionalNavigationOptions { navigationOptions?: NavigationScreenConfig; @@ -304,12 +355,9 @@ declare module 'react-navigation' { declare export type NavigationScreenComponent< Route: NavigationRoute, - Options: {}, - Props: {} - > = React$ComponentType<{ - ...Props, - ...NavigationNavigatorProps, - }> & + Options: {...}, + Props: NavigationNavigatorProps, + > = React$ComponentType & withOptionalNavigationOptions; declare interface withRouter { @@ -318,37 +366,27 @@ declare module 'react-navigation' { declare export type NavigationNavigator< State: NavigationState, - Options: {}, - Props: {} - > = React$ComponentType<{ - ...Props, - ...NavigationNavigatorProps, - }> & + Options: {...}, + Props: NavigationNavigatorProps, + > = React$ComponentType & withRouter & withOptionalNavigationOptions; declare export type NavigationRouteConfig = | NavigationComponent | ({ - navigationOptions?: NavigationScreenConfig<*>, - path?: string, - } & NavigationScreenRouteConfig); + navigationOptions?: NavigationScreenConfig<*>, + path?: string, + ... + } & NavigationScreenRouteConfig); declare export type NavigationScreenRouteConfig = - | { - screen: NavigationComponent, - } - | { - getScreen: () => NavigationComponent, - }; - - declare export type NavigationPathsConfig = { - [routeName: string]: string, - }; + | { screen: NavigationComponent, ... } + | { getScreen: () => NavigationComponent, ... }; - declare export type NavigationRouteConfigMap = { - [routeName: string]: NavigationRouteConfig, - }; + declare export type NavigationPathsConfig = { [routeName: string]: string, ... }; + + declare export type NavigationRouteConfigMap = { [routeName: string]: NavigationRouteConfig, ... }; /** * Header @@ -363,9 +401,10 @@ declare module 'react-navigation' { getScreenDetails: NavigationScene => NavigationScreenDetails< NavigationStackScreenOptions >, - leftInterpolator: (props: NavigationSceneRendererProps) => {}, - titleInterpolator: (props: NavigationSceneRendererProps) => {}, - rightInterpolator: (props: NavigationSceneRendererProps) => {}, + leftInterpolator: (props: NavigationSceneRendererProps) => {...}, + titleInterpolator: (props: NavigationSceneRendererProps) => {...}, + rightInterpolator: (props: NavigationSceneRendererProps) => {...}, + ... } >; @@ -388,18 +427,23 @@ declare module 'react-navigation' { headerPressColorAndroid?: string, headerRight?: React$Node, headerStyle?: ViewStyleProp, - headerForceInset?: HeaderForceInset, + headerForceInset?: _SafeAreaViewInsets, headerBackground?: React$Node | React$ElementType, gesturesEnabled?: boolean, - gestureResponseDistance?: { vertical?: number, horizontal?: number }, + gestureResponseDistance?: { + vertical?: number, + horizontal?: number, + ... + }, gestureDirection?: 'default' | 'inverted', + ... }; declare export type NavigationStackRouterConfig = {| initialRouteName?: string, initialRouteParams?: NavigationParams, paths?: NavigationPathsConfig, - navigationOptions?: NavigationScreenConfig<*>, + defaultNavigationOptions?: NavigationScreenConfig<*>, initialRouteKey?: string, |}; @@ -409,22 +453,30 @@ declare module 'react-navigation' { headerTransitionPreset?: 'fade-in-place' | 'uikit', headerLayoutPreset?: 'left' | 'center', headerBackTitleVisible?: boolean, + cardShadowEnabled?: boolean, + cardOverlayEnabled?: boolean, cardStyle?: ViewStyleProp, transitionConfig?: ( transitionProps: NavigationTransitionProps, prevTransitionProps: ?NavigationTransitionProps, isModal: boolean ) => TransitionConfig, - onTransitionStart?: () => void, - onTransitionEnd?: () => void, + onTransitionStart?: ( + transitionProps: NavigationTransitionProps, + prevTransitionProps: ?NavigationTransitionProps, + ) => void, + onTransitionEnd?: ( + transitionProps: NavigationTransitionProps, + prevTransitionProps: ?NavigationTransitionProps, + ) => void, transparentCard?: boolean, disableKeyboardHandling?: boolean, |}; - declare export type StackNavigatorConfig = {| + declare export type StackNavigatorConfig = $Shape<{| ...NavigationStackViewConfig, ...NavigationStackRouterConfig, - |}; + |}>; /** * Switch Navigator @@ -434,7 +486,7 @@ declare module 'react-navigation' { initialRouteName?: string, initialRouteParams?: NavigationParams, paths?: NavigationPathsConfig, - navigationOptions?: NavigationScreenConfig<*>, + defaultNavigationOptions?: NavigationScreenConfig<*>, order?: Array, backBehavior?: 'none' | 'initialRoute', // defaults to `'none'` resetOnBlur?: boolean, // defaults to `true` @@ -448,7 +500,7 @@ declare module 'react-navigation' { initialRouteName?: string, initialRouteParams?: NavigationParams, paths?: NavigationPathsConfig, - navigationOptions?: NavigationScreenConfig<*>, + defaultNavigationOptions?: NavigationScreenConfig<*>, // todo: type these as the real route names rather than 'string' order?: Array, // Does the back button cause the router to switch to the initial tab @@ -460,22 +512,36 @@ declare module 'react-navigation' { focused: boolean, index: number, tintColor?: ?string, + ... }; declare export type NavigationTabScreenOptions = {| ...$Exact, tabBarIcon?: | React$Node - | ((options: { tintColor: ?string, focused: boolean }) => ?React$Node), + | ((options: { + tintColor: ?string, + focused: boolean, + ... + }) => ?React$Node), tabBarLabel?: | string | React$Node - | ((options: { tintColor: ?string, focused: boolean }) => ?React$Node), + | ((options: { + tintColor: ?string, + focused: boolean, + ... + }) => ?React$Node), tabBarVisible?: boolean, - tabBarTestIDProps?: { testID?: string, accessibilityLabel?: string }, + tabBarTestIDProps?: { + testID?: string, + accessibilityLabel?: string, + ... + }, tabBarOnPress?: ({ navigation: NavigationScreenProp, defaultHandler: () => void, + ... }) => void, |}; @@ -487,10 +553,18 @@ declare module 'react-navigation' { ...$Exact, drawerIcon?: | React$Node - | ((options: { tintColor: ?string, focused: boolean }) => ?React$Node), + | ((options: { + tintColor: ?string, + focused: boolean, + ... + }) => ?React$Node), drawerLabel?: | React$Node - | ((options: { tintColor: ?string, focused: boolean }) => ?React$Node), + | ((options: { + tintColor: ?string, + focused: boolean, + ... + }) => ?React$Node), drawerLockMode?: 'unlocked' | 'locked-closed' | 'locked-open', |}; @@ -505,6 +579,7 @@ declare module 'react-navigation' { declare export type NavigationProp = { +state: S, dispatch: NavigationDispatch, + ... }; declare export type EventType = @@ -519,15 +594,14 @@ declare module 'react-navigation' { action: NavigationAction, state: NavigationState, lastState: ?NavigationState, + ... }; declare export type NavigationEventCallback = ( payload: NavigationEventPayload ) => void; - declare export type NavigationEventSubscription = { - remove: () => void, - }; + declare export type NavigationEventSubscription = { remove: () => void, ... }; declare export type NavigationScreenProp<+S> = { +state: S, @@ -541,7 +615,7 @@ declare module 'react-navigation' { fallback?: $ElementType< $PropertyType< {| - ...{| params: {| [ParamName]: void |} |}, + ...{| params: {...} |}, ...$Exact, |}, 'params' @@ -551,14 +625,14 @@ declare module 'react-navigation' { ) => $ElementType< $PropertyType< {| - ...{| params: {| [ParamName]: void |} |}, + ...{| params: {...} |}, ...$Exact, |}, 'params' >, ParamName >, - dangerouslyGetParent: () => NavigationScreenProp<*>, + dangerouslyGetParent: () => ?NavigationScreenProp, isFocused: () => boolean, // Shared action creators that exist for all routers goBack: (routeKey?: ?string) => boolean, @@ -566,18 +640,19 @@ declare module 'react-navigation' { routeName: | string | { - routeName: string, - params?: NavigationParams, - action?: NavigationNavigateAction, - key?: string, - }, + routeName: string, + params?: NavigationParams, + action?: NavigationNavigateAction, + key?: string, + ... + }, params?: NavigationParams, action?: NavigationNavigateAction ) => boolean, setParams: (newParams: NavigationParams) => boolean, // StackRouter action creators - pop?: (n?: number, params?: { immediate?: boolean }) => boolean, - popToTop?: (params?: { immediate?: boolean }) => boolean, + pop?: (n?: number, params?: { immediate?: boolean, ... }) => boolean, + popToTop?: (params?: { immediate?: boolean, ... }) => boolean, push?: ( routeName: string, params?: NavigationParams, @@ -594,12 +669,14 @@ declare module 'react-navigation' { openDrawer?: () => boolean, closeDrawer?: () => boolean, toggleDrawer?: () => boolean, + ... }; - declare export type NavigationNavigatorProps = $Shape<{ + declare export type NavigationNavigatorProps = $Shape<{ navigation: NavigationScreenProp, - screenProps?: {}, + screenProps?: {...}, navigationOptions?: O, + ... }>; /** @@ -612,6 +689,7 @@ declare module 'react-navigation' { onDidFocus?: NavigationEventCallback, onWillBlur?: NavigationEventCallback, onDidBlur?: NavigationEventCallback, + ... }; declare export var NavigationEvents: React$ComponentType< _NavigationEventsProps @@ -623,16 +701,13 @@ declare module 'react-navigation' { declare export type NavigationContainer< State: NavigationState, - Options: {}, - Props: {} - > = React$StatelessFunctionalComponent<{ - ...Props, - ...NavigationContainerProps, - }> & + Options: {...}, + Props: NavigationContainerProps, + > = React$ComponentType & withRouter & withOptionalNavigationOptions; - declare export type NavigationContainerProps = $Shape<{ + declare export type NavigationContainerProps = $Shape<{ uriPrefix?: string | RegExp, onNavigationStateChange?: ?( NavigationState, @@ -641,9 +716,10 @@ declare module 'react-navigation' { ) => void, navigation?: NavigationScreenProp, persistenceKey?: ?string, - renderLoadingExperimental?: React$ComponentType<{}>, + renderLoadingExperimental?: React$ComponentType<{...}>, screenProps?: *, navigationOptions?: O, + ... }>; /** @@ -658,6 +734,7 @@ declare module 'react-navigation' { initWidth: number, isMeasured: boolean, width: AnimatedValue, + ... }; declare export type NavigationScene = { @@ -666,28 +743,25 @@ declare module 'react-navigation' { isStale: boolean, key: string, route: NavigationRoute, + descriptor: ?NavigationDescriptor, + ... }; declare export type NavigationTransitionProps = $Shape<{ // The layout of the screen container layout: NavigationLayout, - // The destination navigation state of the transition navigation: NavigationScreenProp, - // The progressive index of the transitioner's navigation state. position: AnimatedValue, - // The value that represents the progress of the transition when navigation // state changes from one to another. Its numeric value will range from 0 // to 1. - // progress.__getAnimatedValue() < 1 : transtion is happening. - // progress.__getAnimatedValue() == 1 : transtion completes. + // progress.__getAnimatedValue() < 1 : transition is happening. + // progress.__getAnimatedValue() == 1 : transition completes. progress: AnimatedValue, - // All the scenes of the transitioner. scenes: Array, - // The active scene, corresponding to the route at // `navigation.state.routes[navigation.state.index]`. When rendering // NavigationSceneRendererPropsIndex, the scene does not refer to the active @@ -695,8 +769,8 @@ declare module 'react-navigation' { // is the index of the scene scene: NavigationScene, index: number, - - screenProps?: {}, + screenProps?: {...}, + ... }>; // The scene renderer props are nearly identical to the props used for @@ -711,6 +785,7 @@ declare module 'react-navigation' { easing?: (t: number) => number, // A timing function such as `Animated.timing`. timing?: (value: AnimatedValue, config: any) => any, + ... }; /** @@ -721,15 +796,16 @@ declare module 'react-navigation' { transitionSpec?: NavigationTransitionSpec, // How to animate position and opacity of the screen // based on the value generated by the transitionSpec - screenInterpolator?: (props: NavigationSceneRendererProps) => {}, + screenInterpolator?: (props: NavigationSceneRendererProps) => {...}, // How to animate position and opacity of the header componetns // based on the value generated by the transitionSpec - headerLeftInterpolator?: (props: NavigationSceneRendererProps) => {}, - headerTitleInterpolator?: (props: NavigationSceneRendererProps) => {}, - headerRightInterpolator?: (props: NavigationSceneRendererProps) => {}, + headerLeftInterpolator?: (props: NavigationSceneRendererProps) => {...}, + headerTitleInterpolator?: (props: NavigationSceneRendererProps) => {...}, + headerRightInterpolator?: (props: NavigationSceneRendererProps) => {...}, // The style of the container. Useful when a scene doesn't have // 100% opacity and the underlying container is visible. containerStyle?: ViewStyleProp, + ... }; declare export type NavigationAnimationSetter = ( @@ -744,27 +820,28 @@ declare module 'react-navigation' { props: NavigationSceneRendererProps ) => AnimatedViewStyleProp; - declare export type LayoutEvent = { - nativeEvent: { - layout: { - x: number, - y: number, - width: number, - height: number, - }, - }, - }; + declare export type LayoutEvent = { nativeEvent: { layout: { + x: number, + y: number, + width: number, + height: number, + ... + }, ... }, ... }; declare export type SceneIndicesForInterpolationInputRange = { first: number, last: number, + ... }; /** * Now we type the actual exported module */ - declare export function createNavigationContainer( + declare export function createAppContainer( + Component: NavigationNavigator + ): NavigationContainer; + declare export function createNavigationContainer( Component: NavigationNavigator ): NavigationContainer; @@ -793,6 +870,7 @@ declare module 'react-navigation' { routes: Array, index?: number ) => NavigationState, + ... }; declare export var NavigationActions: { @@ -800,19 +878,21 @@ declare module 'react-navigation' { INIT: 'Navigation/INIT', NAVIGATE: 'Navigation/NAVIGATE', SET_PARAMS: 'Navigation/SET_PARAMS', - - back: (payload?: { key?: ?string }) => NavigationBackAction, - init: (payload?: { params?: NavigationParams }) => NavigationInitAction, + back: (payload?: { key?: ?string, ... }) => NavigationBackAction, + init: (payload?: { params?: NavigationParams, ... }) => NavigationInitAction, navigate: (payload: { routeName: string, params?: ?NavigationParams, action?: ?NavigationNavigateAction, key?: string, + ... }) => NavigationNavigateAction, setParams: (payload: { key: string, params: NavigationParams, + ... }) => NavigationSetParamsAction, + ... }; declare export var StackActions: { @@ -822,34 +902,34 @@ declare module 'react-navigation' { RESET: 'Navigation/RESET', REPLACE: 'Navigation/REPLACE', COMPLETE_TRANSITION: 'Navigation/COMPLETE_TRANSITION', - pop: (payload: { n?: number, immediate?: boolean, + ... }) => NavigationPopAction, - popToTop: (payload: { - immediate?: boolean, - }) => NavigationPopToTopAction, + popToTop: (payload: { immediate?: boolean, ... }) => NavigationPopToTopAction, push: (payload: { routeName: string, params?: NavigationParams, action?: NavigationNavigateAction, key?: string, + ... }) => NavigationPushAction, reset: (payload: { index: number, key?: ?string, actions: Array, + ... }) => NavigationResetAction, replace: (payload: { key?: string, routeName: string, params?: NavigationParams, action?: NavigationNavigateAction, + ... }) => NavigationReplaceAction, - completeTransition: (payload: { - key?: string, - }) => NavigationCompleteTransitionAction, + completeTransition: (payload: { key?: string, ... }) => NavigationCompleteTransitionAction, + ... }; declare export var DrawerActions: { @@ -858,32 +938,27 @@ declare module 'react-navigation' { TOGGLE_DRAWER: 'Navigation/TOGGLE_DRAWER', DRAWER_OPENED: 'Navigation/DRAWER_OPENED', DRAWER_CLOSED: 'Navigation/DRAWER_CLOSED', - - openDrawer: (payload: { - key?: string, - }) => NavigationOpenDrawerAction, - closeDrawer: (payload: { - key?: string, - }) => NavigationCloseDrawerAction, - toggleDrawer: (payload: { - key?: string, - }) => NavigationToggleDrawerAction, + openDrawer: (payload: { key?: string, ... }) => NavigationOpenDrawerAction, + closeDrawer: (payload: { key?: string, ... }) => NavigationCloseDrawerAction, + toggleDrawer: (payload: { key?: string, ... }) => NavigationToggleDrawerAction, + ... }; - declare type _RouterProp = { - router: NavigationRouter, - }; + declare type _RouterProp = { router: NavigationRouter, ... }; - declare type NavigationDescriptor = { + declare export type NavigationDescriptor = { key: string, - state: NavigationLeafRoute | NavigationStateRoute, + state: NavigationRoute, navigation: NavigationScreenProp<*>, - getComponent: () => React$ComponentType<{}>, + getComponent: () => React$ComponentType<{...}>, + ... }; declare type NavigationView = React$ComponentType<{ - descriptors: { [key: string]: NavigationDescriptor }, + descriptors: { [key: string]: NavigationDescriptor, ... }, navigation: NavigationScreenProp, + navigationConfig: *, + ... }>; declare export function createNavigator( @@ -892,19 +967,15 @@ declare module 'react-navigation' { navigatorConfig?: NavigatorConfig ): NavigationNavigator; - declare export function StackNavigator( - routeConfigMap: NavigationRouteConfigMap, - stackConfig?: StackNavigatorConfig - ): NavigationContainer<*, *, *>; declare export function createStackNavigator( routeConfigMap: NavigationRouteConfigMap, stackConfig?: StackNavigatorConfig - ): NavigationContainer<*, *, *>; + ): NavigationNavigator<*, *, *>; declare type _TabViewConfig = {| tabBarComponent?: React$ElementType, tabBarPosition?: 'top' | 'bottom', - tabBarOptions?: {}, + tabBarOptions?: {...}, swipeEnabled?: boolean, animationEnabled?: boolean, configureTransition?: ( @@ -920,59 +991,45 @@ declare module 'react-navigation' { removeClippedSubviews?: boolean, containerOptions?: void, |}; - declare export function TabNavigator( - routeConfigs: NavigationRouteConfigMap, - config?: _TabNavigatorConfig - ): NavigationContainer<*, *, *>; - declare export function createTabNavigator( - routeConfigs: NavigationRouteConfigMap, - config?: _TabNavigatorConfig - ): NavigationContainer<*, *, *>; /* TODO: fix the config for each of these tab navigator types */ declare export function createBottomTabNavigator( routeConfigs: NavigationRouteConfigMap, config?: _TabNavigatorConfig - ): NavigationContainer<*, *, *>; + ): NavigationNavigator<*, *, *>; declare export function createMaterialTopTabNavigator( routeConfigs: NavigationRouteConfigMap, config?: _TabNavigatorConfig - ): NavigationContainer<*, *, *>; + ): NavigationNavigator<*, *, *>; declare type _SwitchNavigatorConfig = {| ...NavigationSwitchRouterConfig, |}; - declare export function SwitchNavigator( - routeConfigs: NavigationRouteConfigMap, - config?: _SwitchNavigatorConfig - ): NavigationContainer<*, *, *>; declare export function createSwitchNavigator( routeConfigs: NavigationRouteConfigMap, config?: _SwitchNavigatorConfig - ): NavigationContainer<*, *, *>; + ): NavigationNavigator<*, *, *>; declare type _DrawerViewConfig = {| drawerLockMode?: 'unlocked' | 'locked-closed' | 'locked-open', drawerWidth?: number | (() => number), drawerPosition?: 'left' | 'right', contentComponent?: React$ElementType, - contentOptions?: {}, + contentOptions?: {...}, style?: ViewStyleProp, useNativeAnimations?: boolean, drawerBackgroundColor?: string, - screenProps?: {}, + overlayColor?: string, + screenProps?: {...}, |}; declare type _DrawerNavigatorConfig = $Exact<{ ...NavigationTabRouterConfig, ..._DrawerViewConfig, containerConfig?: void, + ... }>; - declare export function DrawerNavigator( - routeConfigs: NavigationRouteConfigMap, - config?: _DrawerNavigatorConfig - ): NavigationContainer<*, *, *>; declare export function createDrawerNavigator( routeConfigs: NavigationRouteConfigMap, config?: _DrawerNavigatorConfig - ): NavigationContainer<*, *, *>; + ): NavigationNavigator<*, *, *>; declare export function StackRouter( routeConfigs: NavigationRouteConfigMap, @@ -996,6 +1053,7 @@ declare module 'react-navigation' { transitionProps: NavigationTransitionProps, prevTransitionProps: ?NavigationTransitionProps ) => React$Node, + ... }; declare export var Transitioner: React$ComponentType<_TransitionerProps>; @@ -1010,13 +1068,14 @@ declare module 'react-navigation' { * Optional custom animation when transitioning between screens. */ transitionConfig?: () => TransitionConfig, + ... } & NavigationNavigatorProps; declare export var CardStackTransitioner: React$ComponentType< _CardStackTransitionerProps >; declare type _CardStackProps = { - screenProps?: {}, + screenProps?: {...}, headerMode: HeaderMode, headerComponent?: React$ElementType, mode: 'card' | 'modal', @@ -1036,6 +1095,7 @@ declare module 'react-navigation' { scenes: Array, scene: NavigationScene, index: number, + ... }; declare export var CardStack: React$ComponentType<_CardStackProps>; @@ -1045,32 +1105,35 @@ declare module 'react-navigation' { onComponentRef: React$Ref<*>, pointerEvents: string, style: any, + ... }; declare export var Card: React$ComponentType<_CardProps>; declare type _SafeAreaViewForceInsetValue = 'always' | 'never' | number; + declare type _SafeAreaViewInsets = $Shape<{ + top: _SafeAreaViewForceInsetValue, + bottom: _SafeAreaViewForceInsetValue, + left: _SafeAreaViewForceInsetValue, + right: _SafeAreaViewForceInsetValue, + vertical: _SafeAreaViewForceInsetValue, + horizontal: _SafeAreaViewForceInsetValue, + ... + }>; declare type _SafeAreaViewProps = { - forceInset?: { - top?: _SafeAreaViewForceInsetValue, - bottom?: _SafeAreaViewForceInsetValue, - left?: _SafeAreaViewForceInsetValue, - right?: _SafeAreaViewForceInsetValue, - vertical?: _SafeAreaViewForceInsetValue, - horizontal?: _SafeAreaViewForceInsetValue, - }, + forceInset?: _SafeAreaViewInsets, children?: React$Node, style?: AnimatedViewStyleProp, + ... }; declare export var SafeAreaView: React$ComponentType<_SafeAreaViewProps>; - declare export var Header: React$ComponentType & { - HEIGHT: number, - }; + declare export var Header: React$ComponentType & { HEIGHT: number, ... }; declare type _HeaderTitleProps = { children: React$Node, selectionColor?: string | number, style?: AnimatedTextStyleProp, + ... }; declare export var HeaderTitle: React$ComponentType<_HeaderTitleProps>; @@ -1082,6 +1145,7 @@ declare module 'react-navigation' { tintColor?: ?string, truncatedTitle?: ?string, width?: ?number, + ... }; declare export var HeaderBackButton: React$ComponentType< _HeaderBackButtonProps @@ -1092,13 +1156,14 @@ declare module 'react-navigation' { drawerWidth: number | (() => number), drawerPosition: 'left' | 'right', contentComponent: React$ElementType, - contentOptions?: {}, + contentOptions?: {...}, style?: ViewStyleProp, useNativeAnimations: boolean, drawerBackgroundColor: string, - screenProps?: {}, + screenProps?: {...}, navigation: NavigationScreenProp, router: NavigationRouter, + ... }; declare export var DrawerView: React$ComponentType<_DrawerViewProps>; @@ -1107,10 +1172,12 @@ declare module 'react-navigation' { focused: boolean, index: number, tintColor?: string, + ... }; declare type _DrawerItem = { route: NavigationRoute, focused: boolean, + ... }; declare type _DrawerItemsProps = { navigation: NavigationScreenProp, @@ -1131,13 +1198,14 @@ declare module 'react-navigation' { inactiveLabelStyle?: TextStyleProp, iconContainerStyle?: ViewStyleProp, drawerPosition: 'left' | 'right', + ... }; declare export var DrawerItems: React$ComponentType<_DrawerItemsProps>; declare type _TabViewProps = { tabBarComponent?: React$ElementType, tabBarPosition?: 'top' | 'bottom', - tabBarOptions?: {}, + tabBarOptions?: {...}, swipeEnabled?: boolean, animationEnabled?: boolean, configureTransition?: ( @@ -1145,13 +1213,14 @@ declare module 'react-navigation' { nextTransitionProps: Object ) => Object, initialLayout: TabViewLayout, - screenProps?: {}, + screenProps?: {...}, navigation: NavigationScreenProp, router: NavigationRouter, + ... }; declare export var TabView: React$ComponentType<_TabViewProps>; - declare type _TabBarTopProps = { + declare type _MaterialTopTabBarProps = { activeTintColor: string, inactiveTintColor: string, showIcon: boolean, @@ -1170,14 +1239,26 @@ declare module 'react-navigation' { previousScene: NavigationRoute, scene: TabScene, jumpToIndex: (index: number) => void, + ... }) => void, renderIcon: (scene: TabScene) => React$Element<*>, labelStyle?: TextStyleProp, iconStyle?: ViewStyleProp, + ... }; - declare export var TabBarTop: React$ComponentType<_TabBarTopProps>; + declare export var MaterialTopTabBar: React$ComponentType< + _MaterialTopTabBarProps + >; - declare type _TabBarBottomProps = { + declare type _BottomTabBarButtonComponentProps = { + onPress: () => void, + onLongPress: () => void, + testID: string, + accessibilityLabel: string, + style: ViewStyleProp, + ... + }; + declare type _BottomTabBarProps = { activeTintColor: string, activeBackgroundColor: string, adaptive?: boolean, @@ -1197,37 +1278,48 @@ declare module 'react-navigation' { previousScene: NavigationRoute, scene: TabScene, jumpToIndex: (index: number) => void, + ... }) => void, getTestIDProps: (scene: TabScene) => (scene: TabScene) => any, renderIcon: (scene: TabScene) => React$Node, + getButtonComponent: ( + scene: TabScene + ) => React$ComponentType<_BottomTabBarButtonComponentProps>, style?: ViewStyleProp, animateStyle?: ViewStyleProp, labelStyle?: TextStyleProp, tabStyle?: ViewStyleProp, showIcon?: boolean, + ... }; - declare export var TabBarBottom: React$ComponentType<_TabBarBottomProps>; + declare export var BottomTabBar: React$ComponentType<_BottomTabBarProps>; - declare export function withNavigation( - Component: React$ComponentType + declare export function withNavigation>( + Component: ComponentType ): React$ComponentType< $Diff< - Props, - { - navigation: NavigationScreenProp | void, - } + React$ElementConfig, + { navigation: NavigationScreenProp | void, ... } > >; - declare export function withNavigationFocus( - Component: React$ComponentType - ): React$ComponentType<$Diff>; + declare export function withNavigationFocus>( + Component: ComponentType + ): React$ComponentType<$Diff, { isFocused: boolean | void, ... }>>; - declare export function getNavigation( + declare export function getNavigation( router: NavigationRouter, state: State, dispatch: NavigationDispatch, actionSubscribers: Set, - getScreenProps: () => {}, + getScreenProps: () => {...}, getCurrentNavigation: () => ?NavigationScreenProp ): NavigationScreenProp; + + declare export function getActiveChildNavigationOptions< + State: NavigationState, + Options: {...} + >( + navigation: NavigationScreenProp, + screenProps?: {...} + ): Options; } diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 7b7682faf49..8026c824c65 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -323,6 +323,8 @@ PODS: - React - RNDeviceInfo (0.21.5): - React + - RNGestureHandler (1.8.0): + - React - RNSentry (1.6.3): - React - Sentry (~> 5.1.8) @@ -425,6 +427,7 @@ DEPENDENCIES: - rn-fetch-blob (from `../node_modules/rn-fetch-blob`) - "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)" - RNDeviceInfo (from `../node_modules/react-native-device-info`) + - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) - "RNSentry (from `../node_modules/@sentry/react-native`)" - RNSound (from `../node_modules/react-native-sound`) - RNVectorIcons (from `../node_modules/react-native-vector-icons`) @@ -549,6 +552,8 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-community/async-storage" RNDeviceInfo: :path: "../node_modules/react-native-device-info" + RNGestureHandler: + :path: "../node_modules/react-native-gesture-handler" RNSentry: :path: "../node_modules/@sentry/react-native" RNSound: @@ -640,6 +645,7 @@ SPEC CHECKSUMS: rn-fetch-blob: f525a73a78df9ed5d35e67ea65e79d53c15255bc RNCAsyncStorage: 3c304d1adfaea02ec732ac218801cb13897aa8c0 RNDeviceInfo: e7c5fcde13d40e161d8a27f6c5dc69c638936002 + RNGestureHandler: 7a5833d0f788dbd107fbb913e09aa0c1ff333c39 RNSentry: ae1e005e4f2655775475445a9c49c1d343e8e3a7 RNSound: da030221e6ac7e8290c6b43f2b5f2133a8e225b0 RNVectorIcons: 0bb4def82230be1333ddaeee9fcba45f0b288ed4 diff --git a/jest.config.js b/jest.config.js index 7b16fdf9eb1..174013f8cfe 100644 --- a/jest.config.js +++ b/jest.config.js @@ -45,6 +45,6 @@ module.exports = { globals: { __TEST__: true, }, - setupFiles: ['./jest/globalFetch.js'], + setupFiles: ['./jest/globalFetch.js', './node_modules/react-native-gesture-handler/jestSetup.js'], setupFilesAfterEnv: ['./jest/jestSetup.js', 'jest-extended'], }; diff --git a/package.json b/package.json index 49e7c407898..89d53567f25 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,8 @@ "@react-native-community/async-storage": "^1.6.3", "@react-native-community/cameraroll": "^1.7.2", "@react-native-community/netinfo": "^5.9.5", + "@react-navigation/core": "^3.5.0", + "@react-navigation/native": "^3.6.2", "@sentry/react-native": "^1.0.9", "@unimodules/core": "~5.1.2", "@zulip/shared": "^0.0.2", @@ -60,6 +62,7 @@ "react-native": "0.61.5", "react-native-device-info": "^0.21.5", "react-native-document-picker": "^3.2.4", + "react-native-gesture-handler": "^1.0.12", "react-native-image-picker": "^2.3.3", "react-native-notifications": "^1.2.0", "react-native-photo-view": "alwx/react-native-photo-view#c58fd6b30", @@ -73,9 +76,11 @@ "react-native-url-polyfill": "1.2.0-rc.0", "react-native-vector-icons": "^6.6.0", "react-native-webview": "~10.0.0", - "react-navigation": "^2.18.3", - "react-navigation-redux-helpers": "^2.0.9", - "react-navigation-tabs": "0.8.4", + "react-navigation": "^3.13.0", + "react-navigation-drawer": "~1.4.0", + "react-navigation-redux-helpers": "^3.0.8", + "react-navigation-stack": "1.5.3", + "react-navigation-tabs": "~1.2.0", "react-redux": "^5.0.7", "redux": "^4.0.0", "redux-action-buffer": "^1.2.0", diff --git a/src/boot/store.js b/src/boot/store.js index a2d5300bcd0..d17b20521a5 100644 --- a/src/boot/store.js +++ b/src/boot/store.js @@ -192,7 +192,7 @@ function listMiddleware() { const result = [ // Allow us to cause navigation by dispatching Redux actions. // See docs: https://github.com/react-navigation/redux-helpers - createReactNavigationReduxMiddleware('root', getNav), + createReactNavigationReduxMiddleware(getNav, 'root'), // Delay ("buffer") actions until a REHYDRATE action comes through. // After dispatching the latter, this will go back and dispatch diff --git a/src/nav/AppNavigator.js b/src/nav/AppNavigator.js index c9a524e98b2..082a137688a 100644 --- a/src/nav/AppNavigator.js +++ b/src/nav/AppNavigator.js @@ -71,8 +71,5 @@ export default createStackNavigator( { initialRouteName: 'main', headerMode: 'none', - cardStyle: { - backgroundColor: 'white', - }, }, ); diff --git a/src/nav/AppWithNavigation.js b/src/nav/AppWithNavigation.js index 8e7a8115e3e..45bd8b86ff9 100644 --- a/src/nav/AppWithNavigation.js +++ b/src/nav/AppWithNavigation.js @@ -1,6 +1,6 @@ /* @flow strict-local */ -import { reduxifyNavigator } from 'react-navigation-redux-helpers'; +import { createReduxContainer } from 'react-navigation-redux-helpers'; import { connect } from '../react-redux'; import { getNav } from '../selectors'; @@ -8,4 +8,4 @@ import AppNavigator from './AppNavigator'; export default connect(state => ({ state: getNav(state), -}))(reduxifyNavigator(AppNavigator, 'root')); +}))(createReduxContainer(AppNavigator, 'root')); diff --git a/src/reactions/MessageReactionList.js b/src/reactions/MessageReactionList.js index 373696ce418..f425c36c189 100644 --- a/src/reactions/MessageReactionList.js +++ b/src/reactions/MessageReactionList.js @@ -1,8 +1,9 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; import { View } from 'react-native'; -import { createNavigationContainer, createMaterialTopTabNavigator } from 'react-navigation'; +import { createAppContainer } from 'react-navigation'; import type { NavigationScreenProp } from 'react-navigation'; +import { createMaterialTopTabNavigator } from 'react-navigation-tabs'; import * as logging from '../utils/logging'; import ReactionUserList from './ReactionUserList'; @@ -65,11 +66,19 @@ const getReactionsTabs = ( // It's not feasible to set up our newly created tab navigator as // part of the entire app's navigation (see the note at // `getReactionsTabs`'s call site). Given that, it seems we can use - // `createNavigationContainer` (soon to be called - // `createAppContainer`) so our violation of the "only explicitly - // render one navigator" rule doesn't become a crashing error in - // `react-navigation` v3. - return createNavigationContainer( + // `createAppContainer` so our violation of the "only explicitly + // render one navigator" rule doesn't cause a crashing error. But + // the name `createAppContainer` is enough to suggest that we're + // definitely doing something wrong here. + return createAppContainer( + // TODO: Upgrade to react-navigation v4, so we don't get a red box + // (`console.error`) saying "navigation.emit only supports the + // 'refocus' event currently", on visiting the screen and + // switching tabs. I see no actual breakage of functionality, but + // the message is annoying. + // + // It may be related to + // https://twitter.com/reactnavigation/status/1245276770586288128. createMaterialTopTabNavigator(reactionsTabs, { backBehavior: 'none', diff --git a/yarn.lock b/yarn.lock index 945631d2ec4..1f97074db6e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1011,6 +1011,13 @@ exec-sh "^0.3.2" minimist "^1.2.0" +"@egjs/hammerjs@^2.0.17": + version "2.0.17" + resolved "https://registry.yarnpkg.com/@egjs/hammerjs/-/hammerjs-2.0.17.tgz#5dc02af75a6a06e4c2db0202cae38c9263895124" + integrity sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A== + dependencies: + "@types/hammerjs" "^2.0.36" + "@expo/react-native-action-sheet@^3.4.0": version "3.4.0" resolved "https://registry.yarnpkg.com/@expo/react-native-action-sheet/-/react-native-action-sheet-3.4.0.tgz#b385b650a1296a8f7411ef3cdccbaa5aef8429d5" @@ -1503,6 +1510,42 @@ resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-5.9.5.tgz#3bad0d855d2e813be085ec305139d4175c512ccc" integrity sha512-PbSsRmhRwYIMdeVJTf9gJtvW0TVq/hmgz1xyjsrTIsQ7QS7wbMEiv1Eb/M/y6AEEsdUped5Axm5xykq9TGISHg== +"@react-navigation/core@^3.5.0": + version "3.7.6" + resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.7.6.tgz#e0244fcdc22937825b252197f70308bbe5709c58" + integrity sha512-loYFIn0Boy7C+vYxwcqsBVRFRO1EizZJErdutE6/3Jw6dbzz3Bnzupbw5hckZNB16GckacMwGoepZNIK51IIcg== + dependencies: + hoist-non-react-statics "^3.3.2" + path-to-regexp "^1.8.0" + query-string "^6.11.1" + react-is "^16.13.0" + +"@react-navigation/core@~3.5.1": + version "3.5.2" + resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.5.2.tgz#3a3d147b8419e5839e0f2ad4dea086bd2d307fe3" + integrity sha512-HgKXci1h74aETgm5CXMBoIWG8R7VZG1eUUHYb3BdxwekdiZjW1P/srjiXzsCqFGlsESnVIOIkzT4DqI9J752Bw== + dependencies: + hoist-non-react-statics "^3.3.0" + path-to-regexp "^1.7.0" + query-string "^6.4.2" + react-is "^16.8.6" + +"@react-navigation/native@^3.6.2": + version "3.8.0" + resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.8.0.tgz#35882c3fc2f997ea1a43c12a15088cf4c818fd92" + integrity sha512-Uym5XdNOTpTR6XC4IVa/Shfn12DUF3DUIqch+cpiLNfvauQukVmWoz+Rfxd2faGOzxT12EhrWGFsMJ/8nuTfcw== + dependencies: + hoist-non-react-statics "^3.3.2" + react-native-safe-area-view "^0.14.9" + +"@react-navigation/native@~3.6.2": + version "3.6.5" + resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.6.5.tgz#97b0b9a48f059a0704e3527f40fb034720ef363d" + integrity sha512-ttEmnokFVf09CvrkzlPIdfA693KfYcRxTYf9OZwp0Ll6El27UYjJD4arwGc+zvlohjTErCdba6CAKV702Wv28w== + dependencies: + hoist-non-react-statics "^3.3.2" + react-native-safe-area-view "^0.14.8" + "@rollup/plugin-babel@^5.2.0": version "5.2.0" resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.2.0.tgz#b87556d61ed108b4eaf9d18b5323965adf8d9bee" @@ -1716,6 +1759,11 @@ dependencies: "@types/node" "*" +"@types/hammerjs@^2.0.36": + version "2.0.36" + resolved "https://registry.yarnpkg.com/@types/hammerjs/-/hammerjs-2.0.36.tgz#17ce0a235e9ffbcdcdf5095646b374c2bf615a4c" + integrity sha512-7TUK/k2/QGpEAv/BCwSHlYu3NXZhQ9ZwBYpzr9tjlPIL2C5BeGhH3DmVavRx3ZNyELX5TLC91JTz/cen6AAtIQ== + "@types/hoist-non-react-statics@^3.3.1": version "3.3.1" resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" @@ -2853,11 +2901,6 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== -clamp@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/clamp/-/clamp-1.0.1.tgz#66a0e64011816e37196828fdc8c8c147312c8634" - integrity sha1-ZqDmQBGBbjcZaCj9yMjBRzEshjQ= - class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -3203,14 +3246,6 @@ create-react-class@^15.6.3: loose-envify "^1.3.1" object-assign "^4.1.1" -create-react-context@0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.2.2.tgz#9836542f9aaa22868cd7d4a6f82667df38019dca" - integrity sha512-KkpaLARMhsTsgp0d2NA/R94F/eDLbhXERdIq3LvX2biCAXcDvHYoOqHfWCHf1+OLj+HKBotLG3KqaOOf+C1C+A== - dependencies: - fbjs "^0.8.0" - gud "^1.0.0" - cross-spawn@^5.0.1, cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" @@ -4330,7 +4365,7 @@ fbjs-scripts@^1.1.0: semver "^5.1.0" through2 "^2.0.0" -fbjs@^0.8.0, fbjs@^0.8.9: +fbjs@^0.8.9: version "0.8.17" resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90= @@ -4812,11 +4847,6 @@ growly@^1.3.0: resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= -gud@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0" - integrity sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw== - har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" @@ -4907,15 +4937,15 @@ hermes-engine@^0.2.1: resolved "https://registry.yarnpkg.com/hermes-engine/-/hermes-engine-0.2.1.tgz#25c0f1ff852512a92cb5c5cc47cf967e1e722ea2" integrity sha512-eNHUQHuadDMJARpaqvlCZoK/Nitpj6oywq3vQ3wCwEsww5morX34mW5PmKWQTO7aU0ck0hgulxR+EVDlXygGxQ== -hoist-non-react-statics@^2.2.0, hoist-non-react-statics@^2.3.1, hoist-non-react-statics@^2.5.0: +hoist-non-react-statics@^2.3.1, hoist-non-react-statics@^2.5.0: version "2.5.5" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47" integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw== -hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz#b09178f0122184fb95acf525daaecb4d8f45958b" - integrity sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA== +hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== dependencies: react-is "^16.7.0" @@ -7772,10 +7802,10 @@ path-parse@^1.0.6: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== -path-to-regexp@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" - integrity sha1-Wf3g9DW62suhA6hOnTvGTpa5k30= +path-to-regexp@^1.7.0, path-to-regexp@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" + integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== dependencies: isarray "0.0.1" @@ -8043,7 +8073,7 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.4" -prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -8107,10 +8137,10 @@ query-string@^5.0.1: object-assign "^4.1.0" strict-uri-encode "^1.0.0" -query-string@^6.1.0: - version "6.8.2" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.8.2.tgz#36cb7e452ae11a4b5e9efee83375e0954407b2f6" - integrity sha512-J3Qi8XZJXh93t2FiKyd/7Ec6GNifsjKXUsVFkSBj/kjLsDylWhnCz4NT1bkPcKotttPW+QbKGqqPH8OoI2pdqw== +query-string@^6.11.1, query-string@^6.4.2: + version "6.13.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.13.1.tgz#d913ccfce3b4b3a713989fe6d39466d92e71ccad" + integrity sha512-RfoButmcK+yCta1+FuU8REvisx1oEzhMKwhLUNcepQTPGcNMp1sIqjnfCtfnvGSQZQEhaBHvccujtWoUV3TTbA== dependencies: decode-uri-component "^0.2.0" split-on-first "^1.0.0" @@ -8169,12 +8199,12 @@ react-intl@^2.4.0: intl-relativeformat "^2.1.0" invariant "^2.1.1" -react-is@^16.12.0, react-is@^16.5.2, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4: +react-is@^16.12.0, react-is@^16.13.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-lifecycles-compat@^3, react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.4: +react-lifecycles-compat@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== @@ -8194,29 +8224,20 @@ react-native-device-info@^0.21.5: resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-0.21.5.tgz#99478a2d68182e012297f2d63f2bd1b788106dee" integrity sha512-Bvl7TyVMDbBH3wzvZx0xj3deMhWVRDHdOdjP1MjGVxVVH+bSlCi6oYDScaX2yz5rfi2OvevWWCg8jUqFKeepjA== -react-native-dismiss-keyboard@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/react-native-dismiss-keyboard/-/react-native-dismiss-keyboard-1.0.0.tgz#32886242b3f2317e121f3aeb9b0a585e2b879b49" - integrity sha1-MohiQrPyMX4SHzrrmwpYXiuHm0k= - react-native-document-picker@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/react-native-document-picker/-/react-native-document-picker-3.2.4.tgz#8e1801ba9b81f42f928e8e5e519c3d8e1320cfab" integrity sha512-5l0/fkgasUZdIk9jUUkReDtNCQn2yg1+BrMPHMt45c/NVmE15ThnhIuDj8/n8h1F1RlhUb3SzF86ANK4OdZAiQ== -react-native-drawer-layout-polyfill@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/react-native-drawer-layout-polyfill/-/react-native-drawer-layout-polyfill-1.3.2.tgz#192c84d7a5a6b8a6d2be2c7daa5e4164518d0cc7" - integrity sha512-XzPhfLDJrYHru+e8+dFwhf0FtTeAp7JXPpFYezYV6P1nTeA1Tia/kDpFT+O2DWTrBKBEI8FGhZnThrroZmHIxg== - dependencies: - react-native-drawer-layout "1.3.2" - -react-native-drawer-layout@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/react-native-drawer-layout/-/react-native-drawer-layout-1.3.2.tgz#b9740d7663a1dc4f88a61b9c6d93d2d948ea426e" - integrity sha512-fjO0scqbJUfNu2wuEpvywL7DYLXuCXJ2W/zYhWz986rdLytidbys1QGVvkaszHrb4Y7OqO96mTkgpOcP8KWevw== +react-native-gesture-handler@^1.0.12: + version "1.8.0" + resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.8.0.tgz#18f61f51da50320f938957b0ee79bc58f47449dc" + integrity sha512-E2FZa0qZ5Bi0Z8Jg4n9DaFomHvedSjwbO2DPmUUHYRy1lH2yxXUpSrqJd6yymu+Efzmjg2+JZzsjFYA2Iq8VEQ== dependencies: - react-native-dismiss-keyboard "1.0.0" + "@egjs/hammerjs" "^2.0.17" + hoist-non-react-statics "^3.3.0" + invariant "^2.2.4" + prop-types "^15.7.2" react-native-image-picker@^2.3.3: version "2.3.3" @@ -8242,10 +8263,10 @@ react-native-safari-view@2.0.0: resolved "https://registry.yarnpkg.com/react-native-safari-view/-/react-native-safari-view-2.0.0.tgz#3aeb40693b0765df16b9beaf8654b60c7ff1d7ed" integrity sha1-OutAaTsHZd8Wub6vhlS2DH/x1+0= -react-native-safe-area-view@0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.11.0.tgz#4f3dda43c2bace37965e7c6aef5fc83d4f19d174" - integrity sha512-N3nElaahu1Me2ltnfc9acpgt1znm6pi8DSadKy79kvdzKwvVIzw0IXueA/Hjr51eCW1BsfNw7D1SgBT9U6qEkA== +react-native-safe-area-view@^0.14.8, react-native-safe-area-view@^0.14.9: + version "0.14.9" + resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.9.tgz#90ee8383037010d9a5055a97cf97e4c1da1f0c3d" + integrity sha512-WII/ulhpVyL/qbYb7vydq7dJAfZRBcEhg4/UWt6F6nAKpLa3gAceMOxBxI914ppwSP/TdUsandFy6lkJQE0z4A== dependencies: hoist-non-react-statics "^2.3.1" @@ -8254,7 +8275,7 @@ react-native-safe-area@^0.4.1: resolved "https://registry.yarnpkg.com/react-native-safe-area/-/react-native-safe-area-0.4.4.tgz#c9e267ef06cd6047da854c30e6c955eff7cc7105" integrity sha512-u1RmFqJMmlzqDT5SezAfRv8MCLwteKsB1fPym4J//wy9zIuYJe60Ni664NRwqCKwDyQmwGcvfGqmA1hTpOOhhQ== -react-native-screens@^1.0.0-alpha.11, react-native-screens@^1.0.0-alpha.23: +react-native-screens@^1.0.0-alpha.23: version "1.0.0-alpha.23" resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-1.0.0-alpha.23.tgz#25d7ea4d11bda4fcde2d1da7ae50271c6aa636e0" integrity sha512-tOxHGQUN83MTmQB4ghoQkibqOdGiX4JQEmeyEv96MKWO/x8T2PJv84ECUos9hD3blPRQwVwSpAid1PPPhrVEaw== @@ -8271,14 +8292,7 @@ react-native-sound@^0.11.0: resolved "https://registry.yarnpkg.com/react-native-sound/-/react-native-sound-0.11.0.tgz#ad60b55ba8c6dc89917f381ad3713f2738de530f" integrity sha512-4bGAZfni6E2L695NQjOZwNLBQGXgBGYC4Sy+h99K5h0HqNZjCqR0+aLel+ezASxEJDpaH83gylNObXpiqJgdwg== -react-native-tab-view@^0.0.77: - version "0.0.77" - resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-0.0.77.tgz#11ceb8e7c23100d07e628dc151b57797524d00d4" - integrity sha512-9vjD4Ly1Zlum1Y4g23ODpi/F3gYIUIsKWrsZO/Oh5cuX1eiB1DRVn11nY1z+j/hsQfhfyW6nDlmySyDvYQvYCA== - dependencies: - prop-types "^15.6.0" - -react-native-tab-view@^1.0.0: +react-native-tab-view@^1.2.0, react-native-tab-view@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-1.4.1.tgz#f113cd87485808f0c991abec937f70fa380478b9" integrity sha512-Bke8KkDcDhvB/z0AS7MnQKMD2p6Kwfc1rSKlMOvg9CC5CnClQ2QEnhPSbwegKDYhUkBI92iH/BYy7hNSm5kbUQ== @@ -8374,60 +8388,46 @@ react-native@0.61.5: stacktrace-parser "^0.1.3" whatwg-fetch "^3.0.0" -react-navigation-deprecated-tab-navigator@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/react-navigation-deprecated-tab-navigator/-/react-navigation-deprecated-tab-navigator-1.3.0.tgz#015dcae1e977b984ca7e99245261c15439026bb7" - integrity sha512-Cm+qYOPFWbvvcuv0YYX0ioYwLGgw7XAqdhAfpo3sIr3trxRW8871ePmfFOPezjQtz4v6ItjZt6LPgtBAVZoroQ== - dependencies: - react-native-tab-view "^0.0.77" - -react-navigation-drawer@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/react-navigation-drawer/-/react-navigation-drawer-0.5.0.tgz#d91b6a6ec65c34ba78c00f814b1e6508922cc9ec" - integrity sha512-F1y593uC6pqBMGH+Omz75oNODEbxB/s0EGO8QtYwu1NmOOEUuuLA+c14zm+pgMsI4HlDabiHxPkWqsgGz25xVQ== +react-navigation-drawer@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/react-navigation-drawer/-/react-navigation-drawer-1.4.0.tgz#70f3dd83e3da9cd4ea6e2739526502c823d466b9" + integrity sha512-ZyWBozcjB2aZ7vwCALv90cYA2NpDjM+WALaiYRshvPvue8l7cqynePbHK8GhlMGyJDwZqp4MxQmu8u1XAKp3Bw== dependencies: - react-native-drawer-layout-polyfill "^1.3.2" + react-native-tab-view "^1.2.0" -react-navigation-redux-helpers@^2.0.9: - version "2.0.9" - resolved "https://registry.yarnpkg.com/react-navigation-redux-helpers/-/react-navigation-redux-helpers-2.0.9.tgz#244e7ebbc43481602b1e7948a491b34a312dca06" - integrity sha512-V1eyQ22T1znZeaou38f/JBp5DUV5X2T4hVVSlsjh8dk2unkWhaugzvrgFMF80Mzg1gH4rVE1yADyI9hzuwbbSw== +react-navigation-redux-helpers@^3.0.8: + version "3.0.8" + resolved "https://registry.yarnpkg.com/react-navigation-redux-helpers/-/react-navigation-redux-helpers-3.0.8.tgz#a49024717e5af2d910679afec778743098445367" + integrity sha512-6UQcTXo0V3Q3XkUptXUgd9DFmKJchvw0H5vrNoAaM6Il/37ZkGhF42UGtX4+Lt9QNyQ7+XM4GAeWPuDAreJMsA== dependencies: invariant "^2.2.2" -react-navigation-stack@0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-0.7.0.tgz#0b2f139ee1cba953037ef51353df992ec6c74fa2" - integrity sha512-3Tbb/SsustBrM9R/qaI6XuOfyqYMVbwkeHFC8NbU890vB0aKZvjAtioWLZ18e/4LgbiOCmoTdp37z3gkGDyNDQ== +react-navigation-stack@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-1.5.3.tgz#cdc9f5a6dbdc55509a15f60d765722573dec1997" + integrity sha512-MQcwDVbZUYsTtDJb5cFOSm+K+e7KpUCoROaGoUOR+JHWE3uuaJ3pd/Nu+32a57J98TNBf4qq0+2TPJWl6z6IBg== + dependencies: + prop-types "^15.7.2" -react-navigation-tabs@0.8.4: - version "0.8.4" - resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-0.8.4.tgz#aa767f28b899f13c99f2b034b4a665f8cf0a5737" - integrity sha512-CbS3xIVJVtpu+AYslv0PMLmjddJFVtU3XAhSJ9XnMrKLUJNmnQdW/L0w/Gp5qcBEF9h6bgsY3CoTtp7I6bqyOQ== +react-navigation-tabs@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-1.2.0.tgz#602c147029bb4f1c569b26479ddba534fe3ebb19" + integrity sha512-I6vq3XX4ub9KhWQzcrggznls+2Z2C6w2ro46vokDGGvJ02CBpQRar7J0ETV29Ot5AJY67HucNUmZdH3yDFckmQ== dependencies: hoist-non-react-statics "^2.5.0" prop-types "^15.6.1" - react-lifecycles-compat "^3.0.4" - react-native-tab-view "^1.0.0" - -react-navigation@^2.18.3: - version "2.18.3" - resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-2.18.3.tgz#de9a24dc37dfc33f3e4779a9f13f45ea97dfe19e" - integrity sha512-/5KGMG1Oj5LN/x/7AKF0MWrpX9Qe29307RxEsMCiRT/A4jCYT0DPY99Bl7ZAGtROxExEy3rwTfTrtvpIT+CU7A== - dependencies: - clamp "^1.0.1" - create-react-context "0.2.2" - hoist-non-react-statics "^2.2.0" - path-to-regexp "^1.7.0" - query-string "^6.1.0" - react-is "^16.5.2" - react-lifecycles-compat "^3" - react-native-safe-area-view "0.11.0" - react-native-screens "^1.0.0-alpha.11" - react-navigation-deprecated-tab-navigator "1.3.0" - react-navigation-drawer "0.5.0" - react-navigation-stack "0.7.0" - react-navigation-tabs "0.8.4" + react-native-tab-view "^1.4.1" + +react-navigation@^3.13.0: + version "3.13.0" + resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.13.0.tgz#e802bb5174c1ec8b727c69f8e4409ff1351a5250" + integrity sha512-r64bTImY2aNye8wtd39ubouVB6ZMJqjVQYKxH4LFmOav4FsI59fQTDN7sZzyJa29owowYw/wVkh+NWGT+tdD1A== + dependencies: + "@react-navigation/core" "~3.5.1" + "@react-navigation/native" "~3.6.2" + react-navigation-drawer "~1.4.0" + react-navigation-stack "1.5.3" + react-navigation-tabs "~1.2.0" react-redux@^5.0.7: version "5.1.1" From f3b6c1f9e7d37fb4590007325d17439f0bb15eec Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Thu, 3 Sep 2020 15:20:31 -0700 Subject: [PATCH 5/7] deps: Upgrade to react-navigation v4. v4 includes lots of housekeeping changes that aim to make maintenance easier [1]. In particular, we no longer grab stack, tab, or drawer navigation logic from react-navigation itself; we must now depend directly on separate libraries that provide these and import from them. - We got a head start on this in the v3 upgrade (in a recent commit) by ensuring we had react-navigation-{tabs,stack,drawer} installed at v3-compatible versions. - Now, we bump these to their latest versions (no peer-dep warnings when we do this!) and default to using carets in their version ranges since we see no indication that we can't. - This means installing react-native-reanimated, as we knew we'd need to. (We mock it in our Jest setup, following some instructions [2].) For react-navigation-stack, we add peer dependencies react-native-safe-area-context and @react-native-community/masked-view. The upgrade guide asks us to stop depending on @react-navigation/core and @react-navigation/native and change any imports of those to react-navigation imports instead. We don't have any imports to change, and we can freely remove @react-navigation/native. We can't yet remove @react-navigation/core because it's still a peer dependency of react-navigation-redux-helpers [3]. So we keep it, and align its version range with the one in react-navigation's dependencies. There's a long list of identifiers whose usage has changed. Searching our code for each one, these are the interesting ones: - `create*Navigator` being imported from the respective react-navigation-{tabs,stack,drawer} library; quite easy to handle - `cardStyle` (in stack nav config) being moved to `navigationOptions` (or `defaultNavigationOptions`). We deleted our only use of `cardStyle` in the recent react-navigation v3 upgrade because we only used it to make the background color white and, white became the default background color in that upgrade. Finally, attempt to upgrade libdefs for the dependencies we touched, if we import from them directly. We get new version-appropriate libdefs for react-navigation, react-navigation-drawer, and react-navigation-tabs. Unfortunately react-navigation-stack only has a v1 libdef. [1] https://reactnavigation.org/docs/4.x/upgrading-from-3.x/ [2] See https://reactnavigation.org/docs/testing/. We don't include the following line also recommended there: ``` // Silence the warning: Animated: `useNativeDriver` is not // supported because the native animated module is missing jest.mock('react-native/Libraries/Animated/src/NativeAnimatedHelper'); ``` We don't get that warning in the first place, and it's not clear what mock is being applied (apart from React Native's own default one). If we need to mock `NativeAnimatedHelper` in the future, we shouldn't point to the internal path in react-native; it should go in our existing react-native mock (alongside NativeModules, etc.). [3] https://github.com/zulip/zulip-mobile/issues/3804#issuecomment-686844373 Fixes: #4248 --- .flowconfig | 5 - .../npm/react-navigation-drawer_v2.x.x.js | 688 +++++++++ .../npm/react-navigation-tabs_v2.x.x.js | 781 ++++++++++ flow-typed/npm/react-navigation_v3.x.x.js | 1325 ----------------- flow-typed/npm/react-navigation_v4.x.x.js | 980 ++++++++++++ ios/Podfile.lock | 18 + jest/jestSetup.js | 12 + package.json | 16 +- src/nav/AppNavigator.js | 2 +- yarn.lock | 138 +- 10 files changed, 2554 insertions(+), 1411 deletions(-) create mode 100644 flow-typed/npm/react-navigation-drawer_v2.x.x.js create mode 100644 flow-typed/npm/react-navigation-tabs_v2.x.x.js delete mode 100644 flow-typed/npm/react-navigation_v3.x.x.js create mode 100644 flow-typed/npm/react-navigation_v4.x.x.js diff --git a/.flowconfig b/.flowconfig index 37d5fd4272f..0188efdcf56 100644 --- a/.flowconfig +++ b/.flowconfig @@ -28,11 +28,6 @@ node_modules/warning/.* .*/node_modules/react-native-notifications/.* .*/node_modules/react-native-tab-view/.* - -# Some mistakes in these types got fixed in v2.4.1 of this library, -# but we can't use that until we're on react-navigation v4 (#4248). -.*/node_modules/react-navigation-tabs/.* - .*/node_modules/react-native-safe-area/.* .*/node_modules/flow-coverage-report/.* .*/node_modules/@snyk/.* diff --git a/flow-typed/npm/react-navigation-drawer_v2.x.x.js b/flow-typed/npm/react-navigation-drawer_v2.x.x.js new file mode 100644 index 00000000000..2bc1edcd10b --- /dev/null +++ b/flow-typed/npm/react-navigation-drawer_v2.x.x.js @@ -0,0 +1,688 @@ +// flow-typed signature: 0c2890f004abea22b4179c811d8db7f3 +// flow-typed version: 536c492332/react-navigation-drawer_v2.x.x/flow_>=v0.104.x + +// @flow + +declare module 'react-navigation-drawer' { + + //--------------------------------------------------------------------------- + // SECTION 1: IDENTICAL TYPE DEFINITIONS + // This section is identical across all React Navigation libdefs and contains + // shared definitions. We wish we could make it DRY and import from a shared + // definition, but that isn't yet possible. + //--------------------------------------------------------------------------- + + /** + * SECTION 1A + * We start with some definitions that we have copy-pasted from React Native + * source files. + */ + + // This is a bastardization of the true StyleObj type located in + // react-native/Libraries/StyleSheet/StyleSheetTypes. We unfortunately can't + // import that here, and it's too lengthy (and consequently too brittle) to + // copy-paste here either. + declare type StyleObj = + | null + | void + | number + | false + | '' + | $ReadOnlyArray + | { [name: string]: any, ... }; + declare type ViewStyleProp = StyleObj; + declare type TextStyleProp = StyleObj; + declare type AnimatedViewStyleProp = StyleObj; + declare type AnimatedTextStyleProp = StyleObj; + + /** + * SECTION 1B + * The following are type declarations for core types necessary for every + * React Navigation libdef. + */ + + /** + * Navigation State + Action + */ + + declare export type NavigationParams = { [key: string]: mixed, ... }; + + declare export type NavigationBackAction = {| + type: 'Navigation/BACK', + key?: ?string, + |}; + declare export type NavigationInitAction = {| + type: 'Navigation/INIT', + params?: NavigationParams, + |}; + declare export type NavigationNavigateAction = {| + type: 'Navigation/NAVIGATE', + routeName: string, + params?: NavigationParams, + + // The action to run inside the sub-router + action?: NavigationNavigateAction, + + key?: string, + |}; + declare export type NavigationSetParamsAction = {| + type: 'Navigation/SET_PARAMS', + + // The key of the route where the params should be set + key: string, + + // The new params to merge into the existing route params + params: NavigationParams, + |}; + + declare export type NavigationPopAction = {| + +type: 'Navigation/POP', + +n?: number, + +immediate?: boolean, + |}; + declare export type NavigationPopToTopAction = {| + +type: 'Navigation/POP_TO_TOP', + +immediate?: boolean, + |}; + declare export type NavigationPushAction = {| + +type: 'Navigation/PUSH', + +routeName: string, + +params?: NavigationParams, + +action?: NavigationNavigateAction, + +key?: string, + |}; + declare export type NavigationResetAction = {| + type: 'Navigation/RESET', + index: number, + key?: ?string, + actions: Array, + |}; + declare export type NavigationReplaceAction = {| + +type: 'Navigation/REPLACE', + +key: string, + +routeName: string, + +params?: NavigationParams, + +action?: NavigationNavigateAction, + |}; + declare export type NavigationCompleteTransitionAction = {| + +type: 'Navigation/COMPLETE_TRANSITION', + +key?: string, + +toChildKey?: string, + |}; + + declare export type NavigationOpenDrawerAction = {| + +type: 'Navigation/OPEN_DRAWER', + +key?: string, + |}; + declare export type NavigationCloseDrawerAction = {| + +type: 'Navigation/CLOSE_DRAWER', + +key?: string, + |}; + declare export type NavigationToggleDrawerAction = {| + +type: 'Navigation/TOGGLE_DRAWER', + +key?: string, + |}; + declare export type NavigationDrawerOpenedAction = {| + +type: 'Navigation/DRAWER_OPENED', + +key?: string, + |}; + declare export type NavigationDrawerClosedAction = {| + +type: 'Navigation/DRAWER_CLOSED', + +key?: string, + |}; + + declare export type NavigationJumpToAction = {| + +type: 'Navigation/JUMP_TO'; + +preserveFocus: boolean, + +routeName: string, + +key?: string, + +params?: NavigationParams, + |}; + + declare export type NavigationAction = + | NavigationBackAction + | NavigationInitAction + | NavigationNavigateAction + | NavigationSetParamsAction + | NavigationPopAction + | NavigationPopToTopAction + | NavigationPushAction + | NavigationResetAction + | NavigationReplaceAction + | NavigationCompleteTransitionAction + | NavigationOpenDrawerAction + | NavigationCloseDrawerAction + | NavigationToggleDrawerAction + | NavigationDrawerOpenedAction + | NavigationDrawerClosedAction + | NavigationJumpToAction; + + /** + * NavigationState is a tree of routes for a single navigator, where each + * child route may either be a NavigationScreenRoute or a + * NavigationRouterRoute. NavigationScreenRoute represents a leaf screen, + * while the NavigationRouterRoute represents the state of a child navigator. + * + * NOTE: NavigationState is a state tree local to a single navigator and + * its child navigators (via the routes field). + * If we're in navigator nested deep inside the app, the state will only be + * the state for that navigator. + * The state for the root navigator of our app represents the whole navigation + * state for the whole app. + */ + declare export type NavigationState = { + /** + * Index refers to the active child route in the routes array. + */ + index: number, + routes: Array, + isTransitioning?: bool, + ... + }; + + declare export type NavigationRoute = + | NavigationLeafRoute + | NavigationStateRoute; + + declare export type NavigationLeafRoute = {| + /** + * React's key used by some navigators. No need to specify these manually, + * they will be defined by the router. + */ + key: string, + /** + * For example 'Home'. + * This is used as a key in a route config when creating a navigator. + */ + routeName: string, + /** + * Path is an advanced feature used for deep linking and on the web. + */ + path?: string, + /** + * Params passed to this route when navigating to it, + * e.g. `{ car_id: 123 }` in a route that displays a car. + */ + params?: NavigationParams, + |}; + + declare export type NavigationStateRoute = {| + ...NavigationLeafRoute, + ...$Exact, + |}; + + /** + * Router + */ + + declare export type NavigationScreenProps = { [key: string]: mixed, ... }; + + declare export type NavigationScreenOptionsGetter = ( + navigation: NavigationScreenProp, + screenProps: ?NavigationScreenProps, + theme: SupportedThemes, + ) => Options; + + declare export type NavigationRouter = { + /** + * The reducer that outputs the new navigation state for a given action, + * with an optional previous state. When the action is considered handled + * but the state is unchanged, the output state is null. + */ + getStateForAction: (action: NavigationAction, lastState: ?State) => ?State, + /** + * Maps a URI-like string to an action. This can be mapped to a state + * using `getStateForAction`. + */ + getActionForPathAndParams: ( + path: string, + params?: NavigationParams + ) => ?NavigationAction, + getPathAndParamsForState: ( + state: State + ) => { + path: string, + params?: NavigationParams, + ... + }, + getComponentForRouteName: (routeName: string) => NavigationComponent, + getComponentForState: (state: State) => NavigationComponent, + /** + * Gets the screen navigation options for a given screen. + * + * For example, we could get the config for the 'Foo' screen when the + * `navigation.state` is: + * + * {routeName: 'Foo', key: '123'} + */ + getScreenOptions: NavigationScreenOptionsGetter, + ... + }; + + declare export type NavigationScreenOptions = { title?: string, ... }; + + declare export type SupportedThemes = 'light' | 'dark'; + + declare export type NavigationScreenConfigProps = $Shape<{| + navigation: NavigationScreenProp, + screenProps: NavigationScreenProps, + theme: SupportedThemes, + |}>; + + declare export type NavigationScreenConfig = + | Options + | (({| + ...NavigationScreenConfigProps, + navigationOptions: Options, + |}) => Options); + + declare export type NavigationComponent = + | NavigationScreenComponent + | NavigationNavigator<*, *, *>; + + declare interface withOptionalNavigationOptions { + navigationOptions?: NavigationScreenConfig; + } + + declare export type NavigationScreenComponent< + Route: NavigationRoute, + Options: {...}, + Props: NavigationNavigatorProps, + > = React$ComponentType & + withOptionalNavigationOptions; + + declare interface withRouter { + router: NavigationRouter; + } + + declare export type NavigationNavigator< + State: NavigationState, + Options: {...}, + Props: NavigationNavigatorProps, + > = React$ComponentType & + withRouter & + withOptionalNavigationOptions; + + declare type _NavigationRouteConfigCore = {| + navigationOptions?: NavigationScreenConfig<*>, + params?: NavigationParams, + path?: string, + |}; + declare export type NavigationRouteConfig = + | NavigationComponent + | {| ..._NavigationRouteConfigCore, screen: NavigationComponent |} + | {| ..._NavigationRouteConfigCore, getScreen: () => NavigationComponent |}; + + declare export type NavigationRouteConfigMap = { [routeName: string]: NavigationRouteConfig, ... }; + + /** + * Navigator Prop + */ + + declare export type NavigationDispatch = ( + action: NavigationAction + ) => boolean; + + declare export type EventType = + | 'willFocus' + | 'didFocus' + | 'willBlur' + | 'didBlur' + | 'action'; + + declare export type NavigationEventPayload = {| + type: EventType, + action: NavigationAction, + state: NavigationState, + lastState: ?NavigationState, + |}; + + declare export type NavigationEventCallback = ( + payload: NavigationEventPayload + ) => void; + + declare export type NavigationEventSubscription = {| remove: () => void |}; + + declare export type NavigationScreenProp<+S> = { + +state: S, + dispatch: NavigationDispatch, + addListener: ( + eventName: string, + callback: NavigationEventCallback + ) => NavigationEventSubscription, + getParam: ( + paramName: ParamName, + fallback?: $ElementType< + $PropertyType< + {| + ...{| params: {...} |}, + ...$Exact, + |}, + 'params' + >, + ParamName + > + ) => $ElementType< + $PropertyType< + {| + ...{| params: {...} |}, + ...$Exact, + |}, + 'params' + >, + ParamName + >, + dangerouslyGetParent: () => ?NavigationScreenProp, + isFocused: () => boolean, + goBack: (routeKey?: ?string) => boolean, + dismiss: () => boolean, + navigate: ( + routeName: + | string + | { + routeName: string, + params?: NavigationParams, + action?: NavigationNavigateAction, + key?: string, + ... + }, + params?: NavigationParams, + action?: NavigationNavigateAction + ) => boolean, + setParams: (newParams: NavigationParams) => boolean, + ... + }; + + declare export type NavigationNavigatorProps = $Shape<{ + navigation: NavigationScreenProp, + screenProps?: NavigationScreenProps, + navigationOptions?: O, + theme?: SupportedThemes | 'no-preference', + detached?: boolean, + ... + }>; + + /** + * Navigation container + */ + + declare export type NavigationContainer< + State: NavigationState, + Options: {...}, + Props: NavigationContainerProps, + > = React$ComponentType & + withRouter & + withOptionalNavigationOptions; + + declare export type NavigationContainerProps = $Shape<{ + uriPrefix?: string | RegExp, + onNavigationStateChange?: ?( + NavigationState, + NavigationState, + NavigationAction + ) => void, + navigation?: NavigationScreenProp, + persistenceKey?: ?string, + renderLoadingExperimental?: React$ComponentType<{...}>, + screenProps?: NavigationScreenProps, + navigationOptions?: O, + ... + }>; + + /** + * NavigationDescriptor + */ + + declare export type NavigationDescriptor = { + key: string, + state: NavigationRoute, + navigation: NavigationScreenProp, + getComponent: () => NavigationComponent, + ... + }; + + declare export type NavigationDescriptorMap = { + [key: string]: NavigationDescriptor, + ... + }; + + //--------------------------------------------------------------------------- + // SECTION 2: SHARED TYPE DEFINITIONS + // This section too is copy-pasted, but it's not identical across all React + // Navigation libdefs. We pick out bits and pieces that we need. + //--------------------------------------------------------------------------- + + /** + * SECTION 2A + * We start with definitions we have copy-pasted, either from in-package + * types, other Flow libdefs, or from TypeScript types somewhere. + */ + + // This is copied from react-native-renimated's Typescript libdef + // https://github.com/kmagiera/react-native-reanimated/blob/master/react-native-reanimated.d.ts + declare class AnimatedNode { + constructor( + nodeConfig: {...}, + inputNodes?: $ReadOnlyArray>, + ): void; + isNativelyInitialized(): boolean; + } + + /** + * SECTION 2B + * This section usually contains exported types that are shared by some but + * not all react-navigation libdefs. However, react-navigation-drawer has no + * such types. + */ + + //--------------------------------------------------------------------------- + // SECTION 3: UNIQUE TYPE DEFINITIONS + // This section contains exported types that are not present in any other + // React Navigation libdef. + //--------------------------------------------------------------------------- + + /** + * DrawerRouter + */ + + declare export type NavigationDrawerProp<+S> = + & NavigationScreenProp + & { + jumpTo: (routeName: string, key?: string) => void, + openDrawer: () => boolean, + closeDrawer: () => boolean, + toggleDrawer: () => boolean, + ... + }; + + declare type _Scene = {| + route: NavigationRoute, + index: number, + focused: boolean, + tintColor?: string, + |}; + declare type _ThemedColor = + | string + | {| light: string, dark: string |}; + declare type _DrawerNavigatorItemsProps = {| + items: NavigationRoute[], + activeItemKey?: ?string, + activeTintColor?: _ThemedColor, + activeBackgroundColor?: _ThemedColor, + inactiveTintColor?: _ThemedColor, + inactiveBackgroundColor?: _ThemedColor, + getLabel: (scene: _Scene) => React$Node, + renderIcon: (scene: _Scene) => React$Node, + onItemPress: (scene: {| + route: NavigationRoute, + focused: boolean, + |}) => void, + itemsContainerStyle?: ViewStyleProp, + itemStyle?: ViewStyleProp, + labelStyle?: TextStyleProp, + activeLabelStyle?: TextStyleProp, + inactiveLabelStyle?: TextStyleProp, + iconContainerStyle?: ViewStyleProp, + drawerPosition: 'left' | 'right', + |}; + + declare type _NavigationDrawerState = + & NavigationState + & { isDrawerOpen: boolean, ... }; + declare type _DrawerContentComponentProps = {| + ..._DrawerNavigatorItemsProps, + +navigation: NavigationDrawerProp<_NavigationDrawerState>, + descriptors: NavigationDescriptorMap, + drawerOpenProgress: AnimatedNode, + screenProps: NavigationScreenProps, + |}; + + declare export type NavigationDrawerRouterConfig = {| + navigationOptions?: NavigationScreenConfig<*>, + defaultNavigationOptions?: NavigationScreenConfig<*>, + unmountInactiveRoutes?: boolean, + resetOnBlur?: boolean, + initialRouteName?: string, + contentComponent?: React$ComponentType<_DrawerContentComponentProps>, + contentOptions?: {...}, + backBehavior?: 'none' | 'initialRoute' | 'history', + |}; + + declare export type NavigationDrawerScreenOptions = {| + ...$Exact, + drawerIcon?: + | React$Node + | ((options: {| tintColor: ?string, focused: boolean |}) => ?React$Node), + drawerLabel?: + | React$Node + | ((options: {| tintColor: ?string, focused: boolean |}) => ?React$Node), + drawerLockMode?: 'unlocked' | 'locked-closed' | 'locked-open', + |}; + + /** + * DrawerView + */ + + declare type _DrawerViewProps = {| + edgeWidth: number, + drawerWidth: number | (() => number), + drawerPosition: 'left' | 'right', + drawerType: 'front' | 'back' | 'slide', + statusBarAnimation: 'slide' | 'none' | 'fade', + |}; + declare type _DrawerViewOptionalProps = {| + minSwipeDistance?: number, + drawerLockMode?: 'unlocked' | 'locked-closed' | 'locked-open', + keyboardDismissMode?: 'none' | 'on-drag', + hideStatusBar?: boolean, + drawerBackgroundColor?: _ThemedColor, + overlayColor?: _ThemedColor, + style?: ViewStyleProp, + sceneContainerStyle?: ViewStyleProp, + onDrawerClose?: () => void, + onDrawerOpen?: () => void, + gestureHandlerProps?: {...}, + |}; + declare type _DrawerViewConfig = {| + ...NavigationDrawerRouterConfig, + ..._DrawerViewProps, + ..._DrawerViewOptionalProps, + |}; + + declare type DrawerViewProps = {| + lazy: boolean, + navigation: NavigationDrawerProp<_NavigationDrawerState>, + descriptors: NavigationDescriptorMap, + navigationConfig: _DrawerViewConfig, + screenProps?: NavigationScreenProps, + |}; + + /** + * DrawerNavigator + */ + + declare type _Partial = $Rest; + declare export type DrawerNavigatorConfig = {| + ...NavigationDrawerRouterConfig, + ..._Partial<_DrawerViewProps>, + ..._DrawerViewOptionalProps, + |}; + + //--------------------------------------------------------------------------- + // SECTION 4: EXPORTED MODULE + // This is the only section that types exports. Other sections export types, + // but this section types the module's exports. + //--------------------------------------------------------------------------- + + declare export function createDrawerNavigator( + routeConfigs: NavigationRouteConfigMap, + config?: DrawerNavigatorConfig + ): NavigationNavigator<*, *, *>; + + declare export var DrawerActions: {| + OPEN_DRAWER: 'Navigation/OPEN_DRAWER', + CLOSE_DRAWER: 'Navigation/CLOSE_DRAWER', + TOGGLE_DRAWER: 'Navigation/TOGGLE_DRAWER', + DRAWER_OPENED: 'Navigation/DRAWER_OPENED', + DRAWER_CLOSED: 'Navigation/DRAWER_CLOSED', + + openDrawer: (payload: {| key?: string |}) => NavigationOpenDrawerAction, + closeDrawer: (payload: {| key?: string |}) => NavigationCloseDrawerAction, + toggleDrawer: (payload: {| key?: string |}) => NavigationToggleDrawerAction, + |}; + + declare export function DrawerRouter( + routeConfigs: NavigationRouteConfigMap, + stackConfig?: NavigationDrawerRouterConfig + ): NavigationRouter<*, NavigationDrawerScreenOptions>; + + declare type _DrawerScene = {| + route: NavigationRoute, + focused: boolean, + index: number, + tintColor?: string, + |}; + declare type _DrawerItemsProps = {| + navigation: NavigationDrawerProp<_NavigationDrawerState>, + descriptors: NavigationDescriptorMap, + drawerOpenProgress: AnimatedNode, + screenProps?: NavigationScreenProps, + items: NavigationRoute[], + activeItemKey?: ?string, + activeTintColor?: _ThemedColor, + activeBackgroundColor?: _ThemedColor, + inactiveTintColor?: _ThemedColor, + inactiveBackgroundColor?: _ThemedColor, + getLabel: (scene: _DrawerScene) => React$Node, + renderIcon: (scene: _DrawerScene) => React$Node, + onItemPress: (info: {| + route: NavigationRoute, + focused: boolean, + |}) => void, + itemsContainerStyle?: ViewStyleProp, + itemStyle?: ViewStyleProp, + labelStyle?: TextStyleProp, + activeLabelStyle?: TextStyleProp, + inactiveLabelStyle?: TextStyleProp, + iconContainerStyle?: ViewStyleProp, + drawerPosition: 'left' | 'right', + |}; + declare export var DrawerNavigatorItems: React$ComponentType<_DrawerItemsProps>; + + declare type _DrawerSidebarProps = {| + contentComponent?: React$ComponentType<_DrawerContentComponentProps>, + contentOptions?: {...}, + screenProps?: NavigationScreenProps, + navigation: NavigationDrawerProp<_NavigationDrawerState>, + descriptors: NavigationDescriptorMap, + drawerOpenProgress: AnimatedNode, + drawerPosition: 'left' | 'right', + style?: ViewStyleProp, + |}; + declare export var DrawerSidebar: React$ComponentType<_DrawerSidebarProps>; + + declare export var DrawerView: React$ComponentType; + + declare export var DrawerGestureContext: React$Context>; + +} diff --git a/flow-typed/npm/react-navigation-tabs_v2.x.x.js b/flow-typed/npm/react-navigation-tabs_v2.x.x.js new file mode 100644 index 00000000000..a5d50da92f3 --- /dev/null +++ b/flow-typed/npm/react-navigation-tabs_v2.x.x.js @@ -0,0 +1,781 @@ +// flow-typed signature: 7e33fa8e7793c0fe796908176c9f1608 +// flow-typed version: 536c492332/react-navigation-tabs_v2.x.x/flow_>=v0.104.x + +// @flow + +declare module 'react-navigation-tabs' { + + //--------------------------------------------------------------------------- + // SECTION 1: IDENTICAL TYPE DEFINITIONS + // This section is identical across all React Navigation libdefs and contains + // shared definitions. We wish we could make it DRY and import from a shared + // definition, but that isn't yet possible. + //--------------------------------------------------------------------------- + + /** + * SECTION 1A + * We start with some definitions that we have copy-pasted from React Native + * source files. + */ + + // This is a bastardization of the true StyleObj type located in + // react-native/Libraries/StyleSheet/StyleSheetTypes. We unfortunately can't + // import that here, and it's too lengthy (and consequently too brittle) to + // copy-paste here either. + declare type StyleObj = + | null + | void + | number + | false + | '' + | $ReadOnlyArray + | { [name: string]: any, ... }; + declare type ViewStyleProp = StyleObj; + declare type TextStyleProp = StyleObj; + declare type AnimatedViewStyleProp = StyleObj; + declare type AnimatedTextStyleProp = StyleObj; + + /** + * SECTION 1B + * The following are type declarations for core types necessary for every + * React Navigation libdef. + */ + + /** + * Navigation State + Action + */ + + declare export type NavigationParams = { [key: string]: mixed, ... }; + + declare export type NavigationBackAction = {| + type: 'Navigation/BACK', + key?: ?string, + |}; + declare export type NavigationInitAction = {| + type: 'Navigation/INIT', + params?: NavigationParams, + |}; + declare export type NavigationNavigateAction = {| + type: 'Navigation/NAVIGATE', + routeName: string, + params?: NavigationParams, + + // The action to run inside the sub-router + action?: NavigationNavigateAction, + + key?: string, + |}; + declare export type NavigationSetParamsAction = {| + type: 'Navigation/SET_PARAMS', + + // The key of the route where the params should be set + key: string, + + // The new params to merge into the existing route params + params: NavigationParams, + |}; + + declare export type NavigationPopAction = {| + +type: 'Navigation/POP', + +n?: number, + +immediate?: boolean, + |}; + declare export type NavigationPopToTopAction = {| + +type: 'Navigation/POP_TO_TOP', + +immediate?: boolean, + |}; + declare export type NavigationPushAction = {| + +type: 'Navigation/PUSH', + +routeName: string, + +params?: NavigationParams, + +action?: NavigationNavigateAction, + +key?: string, + |}; + declare export type NavigationResetAction = {| + type: 'Navigation/RESET', + index: number, + key?: ?string, + actions: Array, + |}; + declare export type NavigationReplaceAction = {| + +type: 'Navigation/REPLACE', + +key: string, + +routeName: string, + +params?: NavigationParams, + +action?: NavigationNavigateAction, + |}; + declare export type NavigationCompleteTransitionAction = {| + +type: 'Navigation/COMPLETE_TRANSITION', + +key?: string, + +toChildKey?: string, + |}; + + declare export type NavigationOpenDrawerAction = {| + +type: 'Navigation/OPEN_DRAWER', + +key?: string, + |}; + declare export type NavigationCloseDrawerAction = {| + +type: 'Navigation/CLOSE_DRAWER', + +key?: string, + |}; + declare export type NavigationToggleDrawerAction = {| + +type: 'Navigation/TOGGLE_DRAWER', + +key?: string, + |}; + declare export type NavigationDrawerOpenedAction = {| + +type: 'Navigation/DRAWER_OPENED', + +key?: string, + |}; + declare export type NavigationDrawerClosedAction = {| + +type: 'Navigation/DRAWER_CLOSED', + +key?: string, + |}; + + declare export type NavigationJumpToAction = {| + +type: 'Navigation/JUMP_TO'; + +preserveFocus: boolean, + +routeName: string, + +key?: string, + +params?: NavigationParams, + |}; + + declare export type NavigationAction = + | NavigationBackAction + | NavigationInitAction + | NavigationNavigateAction + | NavigationSetParamsAction + | NavigationPopAction + | NavigationPopToTopAction + | NavigationPushAction + | NavigationResetAction + | NavigationReplaceAction + | NavigationCompleteTransitionAction + | NavigationOpenDrawerAction + | NavigationCloseDrawerAction + | NavigationToggleDrawerAction + | NavigationDrawerOpenedAction + | NavigationDrawerClosedAction + | NavigationJumpToAction; + + /** + * NavigationState is a tree of routes for a single navigator, where each + * child route may either be a NavigationScreenRoute or a + * NavigationRouterRoute. NavigationScreenRoute represents a leaf screen, + * while the NavigationRouterRoute represents the state of a child navigator. + * + * NOTE: NavigationState is a state tree local to a single navigator and + * its child navigators (via the routes field). + * If we're in navigator nested deep inside the app, the state will only be + * the state for that navigator. + * The state for the root navigator of our app represents the whole navigation + * state for the whole app. + */ + declare export type NavigationState = { + /** + * Index refers to the active child route in the routes array. + */ + index: number, + routes: Array, + isTransitioning?: bool, + ... + }; + + declare export type NavigationRoute = + | NavigationLeafRoute + | NavigationStateRoute; + + declare export type NavigationLeafRoute = {| + /** + * React's key used by some navigators. No need to specify these manually, + * they will be defined by the router. + */ + key: string, + /** + * For example 'Home'. + * This is used as a key in a route config when creating a navigator. + */ + routeName: string, + /** + * Path is an advanced feature used for deep linking and on the web. + */ + path?: string, + /** + * Params passed to this route when navigating to it, + * e.g. `{ car_id: 123 }` in a route that displays a car. + */ + params?: NavigationParams, + |}; + + declare export type NavigationStateRoute = {| + ...NavigationLeafRoute, + ...$Exact, + |}; + + /** + * Router + */ + + declare export type NavigationScreenProps = { [key: string]: mixed, ... }; + + declare export type NavigationScreenOptionsGetter = ( + navigation: NavigationScreenProp, + screenProps: ?NavigationScreenProps, + theme: SupportedThemes, + ) => Options; + + declare export type NavigationRouter = { + /** + * The reducer that outputs the new navigation state for a given action, + * with an optional previous state. When the action is considered handled + * but the state is unchanged, the output state is null. + */ + getStateForAction: (action: NavigationAction, lastState: ?State) => ?State, + /** + * Maps a URI-like string to an action. This can be mapped to a state + * using `getStateForAction`. + */ + getActionForPathAndParams: ( + path: string, + params?: NavigationParams + ) => ?NavigationAction, + getPathAndParamsForState: ( + state: State + ) => { + path: string, + params?: NavigationParams, + ... + }, + getComponentForRouteName: (routeName: string) => NavigationComponent, + getComponentForState: (state: State) => NavigationComponent, + /** + * Gets the screen navigation options for a given screen. + * + * For example, we could get the config for the 'Foo' screen when the + * `navigation.state` is: + * + * {routeName: 'Foo', key: '123'} + */ + getScreenOptions: NavigationScreenOptionsGetter, + ... + }; + + declare export type NavigationScreenOptions = { title?: string, ... }; + + declare export type SupportedThemes = 'light' | 'dark'; + + declare export type NavigationScreenConfigProps = $Shape<{| + navigation: NavigationScreenProp, + screenProps: NavigationScreenProps, + theme: SupportedThemes, + |}>; + + declare export type NavigationScreenConfig = + | Options + | (({| + ...NavigationScreenConfigProps, + navigationOptions: Options, + |}) => Options); + + declare export type NavigationComponent = + | NavigationScreenComponent + | NavigationNavigator<*, *, *>; + + declare interface withOptionalNavigationOptions { + navigationOptions?: NavigationScreenConfig; + } + + declare export type NavigationScreenComponent< + Route: NavigationRoute, + Options: {...}, + Props: NavigationNavigatorProps, + > = React$ComponentType & + withOptionalNavigationOptions; + + declare interface withRouter { + router: NavigationRouter; + } + + declare export type NavigationNavigator< + State: NavigationState, + Options: {...}, + Props: NavigationNavigatorProps, + > = React$ComponentType & + withRouter & + withOptionalNavigationOptions; + + declare type _NavigationRouteConfigCore = {| + navigationOptions?: NavigationScreenConfig<*>, + params?: NavigationParams, + path?: string, + |}; + declare export type NavigationRouteConfig = + | NavigationComponent + | {| ..._NavigationRouteConfigCore, screen: NavigationComponent |} + | {| ..._NavigationRouteConfigCore, getScreen: () => NavigationComponent |}; + + declare export type NavigationRouteConfigMap = { [routeName: string]: NavigationRouteConfig, ... }; + + /** + * Navigator Prop + */ + + declare export type NavigationDispatch = ( + action: NavigationAction + ) => boolean; + + declare export type EventType = + | 'willFocus' + | 'didFocus' + | 'willBlur' + | 'didBlur' + | 'action'; + + declare export type NavigationEventPayload = {| + type: EventType, + action: NavigationAction, + state: NavigationState, + lastState: ?NavigationState, + |}; + + declare export type NavigationEventCallback = ( + payload: NavigationEventPayload + ) => void; + + declare export type NavigationEventSubscription = {| remove: () => void |}; + + declare export type NavigationScreenProp<+S> = { + +state: S, + dispatch: NavigationDispatch, + addListener: ( + eventName: string, + callback: NavigationEventCallback + ) => NavigationEventSubscription, + getParam: ( + paramName: ParamName, + fallback?: $ElementType< + $PropertyType< + {| + ...{| params: {...} |}, + ...$Exact, + |}, + 'params' + >, + ParamName + > + ) => $ElementType< + $PropertyType< + {| + ...{| params: {...} |}, + ...$Exact, + |}, + 'params' + >, + ParamName + >, + dangerouslyGetParent: () => ?NavigationScreenProp, + isFocused: () => boolean, + goBack: (routeKey?: ?string) => boolean, + dismiss: () => boolean, + navigate: ( + routeName: + | string + | { + routeName: string, + params?: NavigationParams, + action?: NavigationNavigateAction, + key?: string, + ... + }, + params?: NavigationParams, + action?: NavigationNavigateAction + ) => boolean, + setParams: (newParams: NavigationParams) => boolean, + ... + }; + + declare export type NavigationNavigatorProps = $Shape<{ + navigation: NavigationScreenProp, + screenProps?: NavigationScreenProps, + navigationOptions?: O, + theme?: SupportedThemes | 'no-preference', + detached?: boolean, + ... + }>; + + /** + * Navigation container + */ + + declare export type NavigationContainer< + State: NavigationState, + Options: {...}, + Props: NavigationContainerProps, + > = React$ComponentType & + withRouter & + withOptionalNavigationOptions; + + declare export type NavigationContainerProps = $Shape<{ + uriPrefix?: string | RegExp, + onNavigationStateChange?: ?( + NavigationState, + NavigationState, + NavigationAction + ) => void, + navigation?: NavigationScreenProp, + persistenceKey?: ?string, + renderLoadingExperimental?: React$ComponentType<{...}>, + screenProps?: NavigationScreenProps, + navigationOptions?: O, + ... + }>; + + /** + * NavigationDescriptor + */ + + declare export type NavigationDescriptor = { + key: string, + state: NavigationRoute, + navigation: NavigationScreenProp, + getComponent: () => NavigationComponent, + ... + }; + + declare export type NavigationDescriptorMap = { + [key: string]: NavigationDescriptor, + ... + }; + + //--------------------------------------------------------------------------- + // SECTION 2: SHARED TYPE DEFINITIONS + // This section too is copy-pasted, but it's not identical across all React + // Navigation libdefs. We pick out bits and pieces that we need. + //--------------------------------------------------------------------------- + + /** + * SECTION 2A + * We start with definitions we have copy-pasted, either from in-package + * types, other Flow libdefs, or from TypeScript types somewhere. + */ + + // This is copied from react-native-renimated's Typescript libdef + // https://github.com/kmagiera/react-native-reanimated/blob/master/react-native-reanimated.d.ts + declare class AnimatedNode { + constructor( + nodeConfig: {...}, + inputNodes?: $ReadOnlyArray>, + ): void; + isNativelyInitialized(): boolean; + } + + // This is copied from + // react-native/Libraries/Components/View/ViewAccessibility.js + declare type AccessibilityRole = + | 'none' + | 'button' + | 'link' + | 'search' + | 'image' + | 'keyboardkey' + | 'text' + | 'adjustable' + | 'imagebutton' + | 'header' + | 'summary' + | 'alert' + | 'checkbox' + | 'combobox' + | 'menu' + | 'menubar' + | 'menuitem' + | 'progressbar' + | 'radio' + | 'radiogroup' + | 'scrollbar' + | 'spinbutton' + | 'switch' + | 'tab' + | 'tablist' + | 'timer' + | 'toolbar'; + declare type AccessibilityState = { + disabled?: boolean, + selected?: boolean, + checked?: ?boolean | 'mixed', + busy?: boolean, + expanded?: boolean, + ... + }; + + /** + * SECTION 2B + * The following are the actually useful definitions in Section 2, that are + * used below in section 3, but also in other libdefs. + */ + + declare export type NavigationPathsConfig = { [routeName: string]: string, ... }; + + /** + * SafeAreaView + */ + + declare type _SafeAreaViewForceInsetValue = 'always' | 'never' | number; + declare type _SafeAreaViewInsets = $Shape<{| + top: _SafeAreaViewForceInsetValue, + bottom: _SafeAreaViewForceInsetValue, + left: _SafeAreaViewForceInsetValue, + right: _SafeAreaViewForceInsetValue, + vertical: _SafeAreaViewForceInsetValue, + horizontal: _SafeAreaViewForceInsetValue, + |}>; + + /** + * SwitchRouter + */ + + declare export type NavigationSwitchRouterConfig = {| + initialRouteName?: string, + initialRouteParams?: NavigationParams, + paths?: NavigationPathsConfig, + navigationOptions?: NavigationScreenConfig<*>, + defaultNavigationOptions?: NavigationScreenConfig<*>, + // todo: type these as the real route names rather than 'string' + order?: string[], + // Does the back button cause the router to switch to the initial tab + backBehavior?: 'none' | 'initialRoute' | 'history' | 'order', // defaults `initialRoute` + resetOnBlur?: boolean, + |}; + + /** + * TabRouter + */ + + declare export type NavigationTabProp<+S> = + & NavigationScreenProp + & { jumpTo: (routeName: string, key?: string) => void, ... }; + + declare export type NavigationTabRouterConfig = NavigationSwitchRouterConfig; + + declare export type NavigationTabScreenOptions = { + ...$Exact, + tabBarLabel?: React$Node, + tabBarVisible?: boolean, + tabBarAccessibilityLabel?: string, + tabBarTestID?: string, + tabBarIcon?: + | React$Node + | ((props: {| + focused: boolean, + tintColor?: string, + horizontal?: boolean, + |}) => React$Node), + tabBarOnPress?: (props: {| + navigation: NavigationTabProp, + defaultHandler: () => void, + |}) => void, + tabBarOnLongPress?: (props: {| + navigation: NavigationTabProp, + defaultHandler: () => void, + |}) => void, + ... + }; + + //--------------------------------------------------------------------------- + // SECTION 3: UNIQUE TYPE DEFINITIONS + // This section contains exported types that are not present in any other + // React Navigation libdef. + //--------------------------------------------------------------------------- + + /** + * TabNavigator + */ + + declare type _TabViewLayout = $Shape<{| height: number, width: number |}>; + + declare export type TabNavigatorConfig = {| + ...NavigationTabRouterConfig, + ...$Exact, + tabBarComponent?: React$ElementType, + lazy?: boolean, + |}; + + declare type _MaterialTopTabBarOptions = {| + activeTintColor?: string, + allowFontScaling?: boolean, + bounces?: boolean, + inactiveTintColor?: string, + pressColor?: string, + pressOpacity?: number, + scrollEnabled?: boolean, + showIcon?: boolean, + showLabel?: boolean, + upperCaseLabel?: boolean, + tabStyle?: ViewStyleProp, + indicatorStyle?: ViewStyleProp, + iconStyle?: ViewStyleProp, + labelStyle?: TextStyleProp, + contentContainerStyle?: ViewStyleProp, + style?: ViewStyleProp, + |}; + declare export type MaterialTopTabNavigatorConfig = TabNavigatorConfig<{| + tabBarOptions?: _MaterialTopTabBarOptions, + keyboardDismissMode?: 'none' | 'on-drag', + swipeEnabled?: boolean, + swipeDistanceThreshold?: number, + swipeVelocityThreshold?: number, + initialLayout?: _TabViewLayout, + lazyPlaceholderComponent?: React$ComponentType<{ route: {| + key: string, + routeName: string, + |}, ... }>, + tabBarPosition?: 'top' | 'bottom', + sceneContainerStyle?: ViewStyleProp, + style?: ViewStyleProp, + |}>; + + declare type _ThemedColor = + | string + | {| light: string, dark: string |}; + declare type _LabelPosition = 'beside-icon' | 'below-icon'; + declare type _Orientation = 'horizontal' | 'vertical'; + declare type _BottomTabBarOptions = {| + keyboardHidesTabBar?: boolean, + activeTintColor?: _ThemedColor, + inactiveTintColor?: _ThemedColor, + activeBackgroundColor?: _ThemedColor, + inactiveBackgroundColor?: _ThemedColor, + allowFontScaling?: boolean, + showLabel?: boolean, + showIcon?: boolean, + labelStyle?: TextStyleProp, + tabStyle?: ViewStyleProp, + labelPosition?: + | _LabelPosition + | ((options: {| deviceOrientation: _Orientation |}) => _LabelPosition), + adaptive?: boolean, + safeAreaInset?: _SafeAreaViewInsets, + style?: ViewStyleProp, + |}; + declare export type BottomTabNavigatorConfig = TabNavigatorConfig<{| tabBarOptions?: _BottomTabBarOptions |}>; + + /** + * Tab views + */ + + declare export type TabScene = { + route: NavigationRoute, + focused: boolean, + index: number, + tintColor?: ?string, + ... + }; + + //--------------------------------------------------------------------------- + // SECTION 4: EXPORTED MODULE + // This is the only section that types exports. Other sections export types, + // but this section types the module's exports. + //--------------------------------------------------------------------------- + + declare export function createBottomTabNavigator( + routeConfigs: NavigationRouteConfigMap, + config?: BottomTabNavigatorConfig + ): NavigationNavigator<*, *, *>; + declare export function createMaterialTopTabNavigator( + routeConfigs: NavigationRouteConfigMap, + config?: MaterialTopTabNavigatorConfig + ): NavigationNavigator<*, *, *>; + + declare type _SharedTabBarProps = {| + getAccessibilityLabel: (props: {| route: NavigationRoute |}) => ?string, + getTestID: (props: {| route: NavigationRoute |}) => ?string, + renderIcon: (props: {| + route: NavigationRoute, + focused: boolean, + tintColor?: string, + horizontal?: boolean, + |}) => React$Node, + |}; + + declare type _BottomTabBarButtonComponentProps = { + route: NavigationRoute, + focused: boolean, + onPress: () => void, + onLongPress: () => void, + testID?: string, + accessibilityLabel?: string, + accessibilityRole?: AccessibilityRole, + accessibilityStates?: AccessibilityState[], + style?: ViewStyleProp, + ... + }; + declare type _BottomTabBarProps = {| + ..._BottomTabBarOptions, + ..._SharedTabBarProps, + navigation: NavigationTabProp, + onTabPress: (props: {| route: NavigationRoute |}) => void, + onTabLongPress: (props: {| route: NavigationRoute |}) => void, + getAccessibilityRole: (props: {| route: NavigationRoute |}) => ?AccessibilityRole, + getAccessibilityStates: (props: {| + route: NavigationRoute, + focused: boolean, + |}) => AccessibilityState[], + getButtonComponent: (props: {| route: NavigationRoute |}) => ?React$ComponentType<_BottomTabBarButtonComponentProps>, + getLabelText: (props: {| route: NavigationRoute |}) => + | ((scene: {| + focused: boolean, + tintColor?: string, + orientation?: 'horizontal' | 'vertical', + |}) => ?string) + | ?string, + isLandscape: boolean, + jumpTo: (key: string) => void, + screenProps: NavigationScreenProps, + |}; + declare export var BottomTabBar: React$ComponentType<_BottomTabBarProps>; + + declare type _MaterialTopTabBarProps = {| + ..._MaterialTopTabBarOptions, + ..._SharedTabBarProps, + layout: _TabViewLayout, + position: AnimatedNode, + jumpTo: (key: string) => void, + getLabelText: (scene: {| route: NavigationRoute |}) => + | ((scene: {| + focused: boolean, + tintColor: string, + |}) => ?string) + | ?string, + getAccessible?: (scene: {| route: NavigationRoute |}) => ?boolean, + renderBadge?: (scene: {| route: NavigationRoute |}) => React$Node, + onTabPress?: (scene: {| route: NavigationRoute |}) => void, + onTabLongPress?: (scene: {| route: NavigationRoute |}) => void, + tabBarPosition?: 'top' | 'bottom', + screenProps: NavigationScreenProps, + navigation: NavigationTabProp, + |}; + declare export var MaterialTopTabBar: React$ComponentType< + _MaterialTopTabBarProps + >; + + declare type _TabViewProps = { + ..._SharedTabBarProps, + getLabelText: (props: {| route: NavigationRoute |}) => ?string, + renderScene: (props: {| route: NavigationRoute |}) => React$Node, + onIndexChange: (index: number) => void, + onTabPress: (props: {| route: NavigationRoute |}) => void, + onTabLongPress: (props: {| route: NavigationRoute |}) => void, + navigation: NavigationTabProp, + descriptors: NavigationDescriptorMap, + screenProps?: NavigationScreenProps, + ... + }; + declare export function createTabNavigator< + CustomProps: {...}, + >( + TabView: React$ComponentType<_TabViewProps & CustomProps> + ): ( + routeConfigMap: NavigationRouteConfigMap, + tabConfig?: TabNavigatorConfig + ) => NavigationNavigator<*, *, *>; + +} diff --git a/flow-typed/npm/react-navigation_v3.x.x.js b/flow-typed/npm/react-navigation_v3.x.x.js deleted file mode 100644 index a149eed9c32..00000000000 --- a/flow-typed/npm/react-navigation_v3.x.x.js +++ /dev/null @@ -1,1325 +0,0 @@ -// flow-typed signature: c42f0cec370b12d98c16672216f01404 -// flow-typed version: 036cb66b1b/react-navigation_v3.x.x/flow_>=v0.104.x - -// @flow - -declare module 'react-navigation' { - /** - * First, a bunch of things we would love to import but instead must - * reconstruct (mostly copy-pasted). - */ - - // This is a bastardization of the true StyleObj type located in - // react-native/Libraries/StyleSheet/StyleSheetTypes. We unfortunately can't - // import that here, and it's too lengthy (and consequently too brittle) to - // copy-paste here either. - declare type StyleObj = - | null - | void - | number - | false - | '' - | $ReadOnlyArray - | { [name: string]: any, ... }; - declare type ViewStyleProp = StyleObj; - declare type TextStyleProp = StyleObj; - declare type AnimatedViewStyleProp = StyleObj; - declare type AnimatedTextStyleProp = StyleObj; - - // This is copied from the Layout type in - // react-native-tab-view/src/TabViewTypeDefinitions - declare type TabViewLayout = { - height: number, - width: number, - ... - }; - - // This is copied from react-native/Libraries/Image/ImageSource.js - declare type ImageURISource = { - uri?: string, - bundle?: string, - method?: string, - headers?: Object, - body?: string, - cache?: 'default' | 'reload' | 'force-cache' | 'only-if-cached', - width?: number, - height?: number, - scale?: number, - ... - }; - declare type ImageSource = ImageURISource | number | Array; - - // This is copied from - // react-native/Libraries/Animated/src/nodes/AnimatedInterpolation.js - declare type ExtrapolateType = 'extend' | 'identity' | 'clamp'; - declare type InterpolationConfigType = { - inputRange: Array, - outputRange: Array | Array, - easing?: (input: number) => number, - extrapolate?: ExtrapolateType, - extrapolateLeft?: ExtrapolateType, - extrapolateRight?: ExtrapolateType, - ... - }; - declare class AnimatedInterpolation { - interpolate(config: InterpolationConfigType): AnimatedInterpolation; - } - - // This is copied from - // react-native/Libraries/Animated/src/animations/Animation.js - declare type EndResult = { finished: boolean, ... }; - declare type EndCallback = (result: EndResult) => void; - declare class Animation { - start( - fromValue: number, - onUpdate: (value: number) => void, - onEnd: ?EndCallback, - previousAnimation: ?Animation, - animatedValue: AnimatedValue, - ): void; - stop(): void; - } - - // This is vaguely copied from - // react-native/Libraries/Animated/src/nodes/AnimatedTracking.js - declare class AnimatedTracking { - constructor( - value: AnimatedValue, - parent: any, - animationClass: any, - animationConfig: Object, - callback?: ?EndCallback, - ): void; - update(): void; - } - - // This is vaguely copied from - // react-native/Libraries/Animated/src/nodes/AnimatedValue.js - declare type ValueListenerCallback = (state: { value: number, ... }) => void; - declare class AnimatedValue { - constructor(value: number): void; - setValue(value: number): void; - setOffset(offset: number): void; - flattenOffset(): void; - extractOffset(): void; - addListener(callback: ValueListenerCallback): string; - removeListener(id: string): void; - removeAllListeners(): void; - stopAnimation(callback?: ?(value: number) => void): void; - resetAnimation(callback?: ?(value: number) => void): void; - interpolate(config: InterpolationConfigType): AnimatedInterpolation; - animate(animation: Animation, callback: ?EndCallback): void; - stopTracking(): void; - track(tracking: AnimatedTracking): void; - } - - /** - * Next, all the type declarations - */ - - /** - * Navigation State + Action - */ - - declare export type NavigationParams = { [key: string]: mixed, ... }; - - declare export type NavigationBackAction = {| - type: 'Navigation/BACK', - key?: ?string, - |}; - declare export type NavigationInitAction = {| - type: 'Navigation/INIT', - params?: NavigationParams, - |}; - declare export type NavigationNavigateAction = {| - type: 'Navigation/NAVIGATE', - routeName: string, - params?: NavigationParams, - - // The action to run inside the sub-router - action?: NavigationNavigateAction, - - key?: string, - |}; - declare export type NavigationSetParamsAction = {| - type: 'Navigation/SET_PARAMS', - - // The key of the route where the params should be set - key: string, - - // The new params to merge into the existing route params - params: NavigationParams, - |}; - - declare export type NavigationPopAction = {| - +type: 'Navigation/POP', - +n?: number, - +immediate?: boolean, - |}; - declare export type NavigationPopToTopAction = {| - +type: 'Navigation/POP_TO_TOP', - +immediate?: boolean, - |}; - declare export type NavigationPushAction = {| - +type: 'Navigation/PUSH', - +routeName: string, - +params?: NavigationParams, - +action?: NavigationNavigateAction, - +key?: string, - |}; - declare export type NavigationResetAction = {| - type: 'Navigation/RESET', - index: number, - key?: ?string, - actions: Array, - |}; - declare export type NavigationReplaceAction = {| - +type: 'Navigation/REPLACE', - +key: string, - +routeName: string, - +params?: NavigationParams, - +action?: NavigationNavigateAction, - |}; - declare export type NavigationCompleteTransitionAction = {| - +type: 'Navigation/COMPLETE_TRANSITION', - +key?: string, - |}; - - declare export type NavigationOpenDrawerAction = {| - +type: 'Navigation/OPEN_DRAWER', - +key?: string, - |}; - declare export type NavigationCloseDrawerAction = {| - +type: 'Navigation/CLOSE_DRAWER', - +key?: string, - |}; - declare export type NavigationToggleDrawerAction = {| - +type: 'Navigation/TOGGLE_DRAWER', - +key?: string, - |}; - declare export type NavigationDrawerOpenedAction = {| - +type: 'Navigation/DRAWER_OPENED', - +key?: string, - |}; - declare export type NavigationDrawerClosedAction = {| - +type: 'Navigation/DRAWER_CLOSED', - +key?: string, - |}; - - declare export type NavigationAction = - | NavigationBackAction - | NavigationInitAction - | NavigationNavigateAction - | NavigationSetParamsAction - | NavigationPopAction - | NavigationPopToTopAction - | NavigationPushAction - | NavigationResetAction - | NavigationReplaceAction - | NavigationCompleteTransitionAction - | NavigationOpenDrawerAction - | NavigationCloseDrawerAction - | NavigationToggleDrawerAction - | NavigationDrawerOpenedAction - | NavigationDrawerClosedAction; - - /** - * NavigationState is a tree of routes for a single navigator, where each - * child route may either be a NavigationScreenRoute or a - * NavigationRouterRoute. NavigationScreenRoute represents a leaf screen, - * while the NavigationRouterRoute represents the state of a child navigator. - * - * NOTE: NavigationState is a state tree local to a single navigator and - * its child navigators (via the routes field). - * If we're in navigator nested deep inside the app, the state will only be - * the state for that navigator. - * The state for the root navigator of our app represents the whole navigation - * state for the whole app. - */ - declare export type NavigationState = { - /** - * Index refers to the active child route in the routes array. - */ - index: number, - routes: Array, - isTransitioning?: bool, - ... - }; - - declare export type NavigationRoute = - | NavigationLeafRoute - | NavigationStateRoute; - - declare export type NavigationLeafRoute = {| - /** - * React's key used by some navigators. No need to specify these manually, - * they will be defined by the router. - */ - key: string, - /** - * For example 'Home'. - * This is used as a key in a route config when creating a navigator. - */ - routeName: string, - /** - * Path is an advanced feature used for deep linking and on the web. - */ - path?: string, - /** - * Params passed to this route when navigating to it, - * e.g. `{ car_id: 123 }` in a route that displays a car. - */ - params?: NavigationParams, - |}; - - declare export type NavigationStateRoute = {| - ...NavigationLeafRoute, - ...$Exact, - |}; - - /** - * Router - */ - - declare export type NavigationScreenOptionsGetter = ( - navigation: NavigationScreenProp, - screenProps?: {...} - ) => Options; - - declare export type NavigationRouter = { - /** - * The reducer that outputs the new navigation state for a given action, - * with an optional previous state. When the action is considered handled - * but the state is unchanged, the output state is null. - */ - getStateForAction: (action: NavigationAction, lastState: ?State) => ?State, - /** - * Maps a URI-like string to an action. This can be mapped to a state - * using `getStateForAction`. - */ - getActionForPathAndParams: ( - path: string, - params?: NavigationParams - ) => ?NavigationAction, - getPathAndParamsForState: ( - state: State - ) => { - path: string, - params?: NavigationParams, - ... - }, - getComponentForRouteName: (routeName: string) => NavigationComponent, - getComponentForState: (state: State) => NavigationComponent, - /** - * Gets the screen navigation options for a given screen. - * - * For example, we could get the config for the 'Foo' screen when the - * `navigation.state` is: - * - * {routeName: 'Foo', key: '123'} - */ - getScreenOptions: NavigationScreenOptionsGetter, - ... - }; - - declare export type NavigationScreenDetails = { - options: T, - state: NavigationRoute, - navigation: NavigationScreenProp, - ... - }; - - declare export type NavigationScreenOptions = { title?: string, ... }; - - declare export type NavigationScreenConfigProps = $Shape<{ - navigation: NavigationScreenProp, - screenProps: {...}, - ... - }>; - - declare export type NavigationScreenConfig = - | Options - | (({ - ...$Exact, - navigationOptions: Options, - ... - }) => Options); - - declare export type NavigationComponent = - | NavigationScreenComponent - | NavigationNavigator<*, *, *>; - - declare interface withOptionalNavigationOptions { - navigationOptions?: NavigationScreenConfig; - } - - declare export type NavigationScreenComponent< - Route: NavigationRoute, - Options: {...}, - Props: NavigationNavigatorProps, - > = React$ComponentType & - withOptionalNavigationOptions; - - declare interface withRouter { - router: NavigationRouter; - } - - declare export type NavigationNavigator< - State: NavigationState, - Options: {...}, - Props: NavigationNavigatorProps, - > = React$ComponentType & - withRouter & - withOptionalNavigationOptions; - - declare export type NavigationRouteConfig = - | NavigationComponent - | ({ - navigationOptions?: NavigationScreenConfig<*>, - path?: string, - ... - } & NavigationScreenRouteConfig); - - declare export type NavigationScreenRouteConfig = - | { screen: NavigationComponent, ... } - | { getScreen: () => NavigationComponent, ... }; - - declare export type NavigationPathsConfig = { [routeName: string]: string, ... }; - - declare export type NavigationRouteConfigMap = { [routeName: string]: NavigationRouteConfig, ... }; - - /** - * Header - */ - - declare export type HeaderMode = 'float' | 'screen' | 'none'; - - declare export type HeaderProps = $Shape< - NavigationSceneRendererProps & { - mode: HeaderMode, - router: NavigationRouter, - getScreenDetails: NavigationScene => NavigationScreenDetails< - NavigationStackScreenOptions - >, - leftInterpolator: (props: NavigationSceneRendererProps) => {...}, - titleInterpolator: (props: NavigationSceneRendererProps) => {...}, - rightInterpolator: (props: NavigationSceneRendererProps) => {...}, - ... - } - >; - - /** - * Stack Navigator - */ - - declare export type NavigationStackScreenOptions = NavigationScreenOptions & { - header?: ?(React$Node | (HeaderProps => React$Node)), - headerTransparent?: boolean, - headerTitle?: string | React$Node | React$ElementType, - headerTitleStyle?: AnimatedTextStyleProp, - headerTitleAllowFontScaling?: boolean, - headerTintColor?: string, - headerLeft?: React$Node | React$ElementType, - headerBackTitle?: ?string, - headerBackImage?: React$Node | React$ElementType, - headerTruncatedBackTitle?: string, - headerBackTitleStyle?: TextStyleProp, - headerPressColorAndroid?: string, - headerRight?: React$Node, - headerStyle?: ViewStyleProp, - headerForceInset?: _SafeAreaViewInsets, - headerBackground?: React$Node | React$ElementType, - gesturesEnabled?: boolean, - gestureResponseDistance?: { - vertical?: number, - horizontal?: number, - ... - }, - gestureDirection?: 'default' | 'inverted', - ... - }; - - declare export type NavigationStackRouterConfig = {| - initialRouteName?: string, - initialRouteParams?: NavigationParams, - paths?: NavigationPathsConfig, - defaultNavigationOptions?: NavigationScreenConfig<*>, - initialRouteKey?: string, - |}; - - declare export type NavigationStackViewConfig = {| - mode?: 'card' | 'modal', - headerMode?: HeaderMode, - headerTransitionPreset?: 'fade-in-place' | 'uikit', - headerLayoutPreset?: 'left' | 'center', - headerBackTitleVisible?: boolean, - cardShadowEnabled?: boolean, - cardOverlayEnabled?: boolean, - cardStyle?: ViewStyleProp, - transitionConfig?: ( - transitionProps: NavigationTransitionProps, - prevTransitionProps: ?NavigationTransitionProps, - isModal: boolean - ) => TransitionConfig, - onTransitionStart?: ( - transitionProps: NavigationTransitionProps, - prevTransitionProps: ?NavigationTransitionProps, - ) => void, - onTransitionEnd?: ( - transitionProps: NavigationTransitionProps, - prevTransitionProps: ?NavigationTransitionProps, - ) => void, - transparentCard?: boolean, - disableKeyboardHandling?: boolean, - |}; - - declare export type StackNavigatorConfig = $Shape<{| - ...NavigationStackViewConfig, - ...NavigationStackRouterConfig, - |}>; - - /** - * Switch Navigator - */ - - declare export type NavigationSwitchRouterConfig = {| - initialRouteName?: string, - initialRouteParams?: NavigationParams, - paths?: NavigationPathsConfig, - defaultNavigationOptions?: NavigationScreenConfig<*>, - order?: Array, - backBehavior?: 'none' | 'initialRoute', // defaults to `'none'` - resetOnBlur?: boolean, // defaults to `true` - |}; - - /** - * Tab Navigator - */ - - declare export type NavigationTabRouterConfig = {| - initialRouteName?: string, - initialRouteParams?: NavigationParams, - paths?: NavigationPathsConfig, - defaultNavigationOptions?: NavigationScreenConfig<*>, - // todo: type these as the real route names rather than 'string' - order?: Array, - // Does the back button cause the router to switch to the initial tab - backBehavior?: 'none' | 'initialRoute', // defaults `initialRoute` - |}; - - declare type TabScene = { - route: NavigationRoute, - focused: boolean, - index: number, - tintColor?: ?string, - ... - }; - - declare export type NavigationTabScreenOptions = {| - ...$Exact, - tabBarIcon?: - | React$Node - | ((options: { - tintColor: ?string, - focused: boolean, - ... - }) => ?React$Node), - tabBarLabel?: - | string - | React$Node - | ((options: { - tintColor: ?string, - focused: boolean, - ... - }) => ?React$Node), - tabBarVisible?: boolean, - tabBarTestIDProps?: { - testID?: string, - accessibilityLabel?: string, - ... - }, - tabBarOnPress?: ({ - navigation: NavigationScreenProp, - defaultHandler: () => void, - ... - }) => void, - |}; - - /** - * Drawer - */ - - declare export type NavigationDrawerScreenOptions = {| - ...$Exact, - drawerIcon?: - | React$Node - | ((options: { - tintColor: ?string, - focused: boolean, - ... - }) => ?React$Node), - drawerLabel?: - | React$Node - | ((options: { - tintColor: ?string, - focused: boolean, - ... - }) => ?React$Node), - drawerLockMode?: 'unlocked' | 'locked-closed' | 'locked-open', - |}; - - /** - * Navigator Prop - */ - - declare export type NavigationDispatch = ( - action: NavigationAction - ) => boolean; - - declare export type NavigationProp = { - +state: S, - dispatch: NavigationDispatch, - ... - }; - - declare export type EventType = - | 'willFocus' - | 'didFocus' - | 'willBlur' - | 'didBlur' - | 'action'; - - declare export type NavigationEventPayload = { - type: EventType, - action: NavigationAction, - state: NavigationState, - lastState: ?NavigationState, - ... - }; - - declare export type NavigationEventCallback = ( - payload: NavigationEventPayload - ) => void; - - declare export type NavigationEventSubscription = { remove: () => void, ... }; - - declare export type NavigationScreenProp<+S> = { - +state: S, - dispatch: NavigationDispatch, - addListener: ( - eventName: string, - callback: NavigationEventCallback - ) => NavigationEventSubscription, - getParam: ( - paramName: ParamName, - fallback?: $ElementType< - $PropertyType< - {| - ...{| params: {...} |}, - ...$Exact, - |}, - 'params' - >, - ParamName - > - ) => $ElementType< - $PropertyType< - {| - ...{| params: {...} |}, - ...$Exact, - |}, - 'params' - >, - ParamName - >, - dangerouslyGetParent: () => ?NavigationScreenProp, - isFocused: () => boolean, - // Shared action creators that exist for all routers - goBack: (routeKey?: ?string) => boolean, - navigate: ( - routeName: - | string - | { - routeName: string, - params?: NavigationParams, - action?: NavigationNavigateAction, - key?: string, - ... - }, - params?: NavigationParams, - action?: NavigationNavigateAction - ) => boolean, - setParams: (newParams: NavigationParams) => boolean, - // StackRouter action creators - pop?: (n?: number, params?: { immediate?: boolean, ... }) => boolean, - popToTop?: (params?: { immediate?: boolean, ... }) => boolean, - push?: ( - routeName: string, - params?: NavigationParams, - action?: NavigationNavigateAction - ) => boolean, - replace?: ( - routeName: string, - params?: NavigationParams, - action?: NavigationNavigateAction - ) => boolean, - reset?: (actions: NavigationAction[], index: number) => boolean, - dismiss?: () => boolean, - // DrawerRouter action creators - openDrawer?: () => boolean, - closeDrawer?: () => boolean, - toggleDrawer?: () => boolean, - ... - }; - - declare export type NavigationNavigatorProps = $Shape<{ - navigation: NavigationScreenProp, - screenProps?: {...}, - navigationOptions?: O, - ... - }>; - - /** - * NavigationEvents component - */ - - declare type _NavigationEventsProps = { - navigation?: NavigationScreenProp, - onWillFocus?: NavigationEventCallback, - onDidFocus?: NavigationEventCallback, - onWillBlur?: NavigationEventCallback, - onDidBlur?: NavigationEventCallback, - ... - }; - declare export var NavigationEvents: React$ComponentType< - _NavigationEventsProps - >; - - /** - * Navigation container - */ - - declare export type NavigationContainer< - State: NavigationState, - Options: {...}, - Props: NavigationContainerProps, - > = React$ComponentType & - withRouter & - withOptionalNavigationOptions; - - declare export type NavigationContainerProps = $Shape<{ - uriPrefix?: string | RegExp, - onNavigationStateChange?: ?( - NavigationState, - NavigationState, - NavigationAction - ) => void, - navigation?: NavigationScreenProp, - persistenceKey?: ?string, - renderLoadingExperimental?: React$ComponentType<{...}>, - screenProps?: *, - navigationOptions?: O, - ... - }>; - - /** - * Gestures, Animations, and Interpolators - */ - - declare export type NavigationGestureDirection = 'horizontal' | 'vertical'; - - declare export type NavigationLayout = { - height: AnimatedValue, - initHeight: number, - initWidth: number, - isMeasured: boolean, - width: AnimatedValue, - ... - }; - - declare export type NavigationScene = { - index: number, - isActive: boolean, - isStale: boolean, - key: string, - route: NavigationRoute, - descriptor: ?NavigationDescriptor, - ... - }; - - declare export type NavigationTransitionProps = $Shape<{ - // The layout of the screen container - layout: NavigationLayout, - // The destination navigation state of the transition - navigation: NavigationScreenProp, - // The progressive index of the transitioner's navigation state. - position: AnimatedValue, - // The value that represents the progress of the transition when navigation - // state changes from one to another. Its numeric value will range from 0 - // to 1. - // progress.__getAnimatedValue() < 1 : transition is happening. - // progress.__getAnimatedValue() == 1 : transition completes. - progress: AnimatedValue, - // All the scenes of the transitioner. - scenes: Array, - // The active scene, corresponding to the route at - // `navigation.state.routes[navigation.state.index]`. When rendering - // NavigationSceneRendererPropsIndex, the scene does not refer to the active - // scene, but instead the scene that is being rendered. The index always - // is the index of the scene - scene: NavigationScene, - index: number, - screenProps?: {...}, - ... - }>; - - // The scene renderer props are nearly identical to the props used for - // rendering a transition. The exception is that the passed scene is not the - // active scene but is instead the scene that the renderer should render - // content for. - declare export type NavigationSceneRendererProps = NavigationTransitionProps; - - declare export type NavigationTransitionSpec = { - duration?: number, - // An easing function from `Easing`. - easing?: (t: number) => number, - // A timing function such as `Animated.timing`. - timing?: (value: AnimatedValue, config: any) => any, - ... - }; - - /** - * Describes a visual transition from one screen to another. - */ - declare export type TransitionConfig = { - // The basics properties of the animation, such as duration and easing - transitionSpec?: NavigationTransitionSpec, - // How to animate position and opacity of the screen - // based on the value generated by the transitionSpec - screenInterpolator?: (props: NavigationSceneRendererProps) => {...}, - // How to animate position and opacity of the header componetns - // based on the value generated by the transitionSpec - headerLeftInterpolator?: (props: NavigationSceneRendererProps) => {...}, - headerTitleInterpolator?: (props: NavigationSceneRendererProps) => {...}, - headerRightInterpolator?: (props: NavigationSceneRendererProps) => {...}, - // The style of the container. Useful when a scene doesn't have - // 100% opacity and the underlying container is visible. - containerStyle?: ViewStyleProp, - ... - }; - - declare export type NavigationAnimationSetter = ( - position: AnimatedValue, - newState: NavigationState, - lastState: NavigationState - ) => void; - - declare export type NavigationSceneRenderer = () => React$Node; - - declare export type NavigationStyleInterpolator = ( - props: NavigationSceneRendererProps - ) => AnimatedViewStyleProp; - - declare export type LayoutEvent = { nativeEvent: { layout: { - x: number, - y: number, - width: number, - height: number, - ... - }, ... }, ... }; - - declare export type SceneIndicesForInterpolationInputRange = { - first: number, - last: number, - ... - }; - - /** - * Now we type the actual exported module - */ - - declare export function createAppContainer( - Component: NavigationNavigator - ): NavigationContainer; - declare export function createNavigationContainer( - Component: NavigationNavigator - ): NavigationContainer; - - declare export var StateUtils: { - get: (state: NavigationState, key: string) => ?NavigationRoute, - indexOf: (state: NavigationState, key: string) => number, - has: (state: NavigationState, key: string) => boolean, - push: (state: NavigationState, route: NavigationRoute) => NavigationState, - pop: (state: NavigationState) => NavigationState, - jumpToIndex: (state: NavigationState, index: number) => NavigationState, - jumpTo: (state: NavigationState, key: string) => NavigationState, - back: (state: NavigationState) => NavigationState, - forward: (state: NavigationState) => NavigationState, - replaceAt: ( - state: NavigationState, - key: string, - route: NavigationRoute - ) => NavigationState, - replaceAtIndex: ( - state: NavigationState, - index: number, - route: NavigationRoute - ) => NavigationState, - reset: ( - state: NavigationState, - routes: Array, - index?: number - ) => NavigationState, - ... - }; - - declare export var NavigationActions: { - BACK: 'Navigation/BACK', - INIT: 'Navigation/INIT', - NAVIGATE: 'Navigation/NAVIGATE', - SET_PARAMS: 'Navigation/SET_PARAMS', - back: (payload?: { key?: ?string, ... }) => NavigationBackAction, - init: (payload?: { params?: NavigationParams, ... }) => NavigationInitAction, - navigate: (payload: { - routeName: string, - params?: ?NavigationParams, - action?: ?NavigationNavigateAction, - key?: string, - ... - }) => NavigationNavigateAction, - setParams: (payload: { - key: string, - params: NavigationParams, - ... - }) => NavigationSetParamsAction, - ... - }; - - declare export var StackActions: { - POP: 'Navigation/POP', - POP_TO_TOP: 'Navigation/POP_TO_TOP', - PUSH: 'Navigation/PUSH', - RESET: 'Navigation/RESET', - REPLACE: 'Navigation/REPLACE', - COMPLETE_TRANSITION: 'Navigation/COMPLETE_TRANSITION', - pop: (payload: { - n?: number, - immediate?: boolean, - ... - }) => NavigationPopAction, - popToTop: (payload: { immediate?: boolean, ... }) => NavigationPopToTopAction, - push: (payload: { - routeName: string, - params?: NavigationParams, - action?: NavigationNavigateAction, - key?: string, - ... - }) => NavigationPushAction, - reset: (payload: { - index: number, - key?: ?string, - actions: Array, - ... - }) => NavigationResetAction, - replace: (payload: { - key?: string, - routeName: string, - params?: NavigationParams, - action?: NavigationNavigateAction, - ... - }) => NavigationReplaceAction, - completeTransition: (payload: { key?: string, ... }) => NavigationCompleteTransitionAction, - ... - }; - - declare export var DrawerActions: { - OPEN_DRAWER: 'Navigation/OPEN_DRAWER', - CLOSE_DRAWER: 'Navigation/CLOSE_DRAWER', - TOGGLE_DRAWER: 'Navigation/TOGGLE_DRAWER', - DRAWER_OPENED: 'Navigation/DRAWER_OPENED', - DRAWER_CLOSED: 'Navigation/DRAWER_CLOSED', - openDrawer: (payload: { key?: string, ... }) => NavigationOpenDrawerAction, - closeDrawer: (payload: { key?: string, ... }) => NavigationCloseDrawerAction, - toggleDrawer: (payload: { key?: string, ... }) => NavigationToggleDrawerAction, - ... - }; - - declare type _RouterProp = { router: NavigationRouter, ... }; - - declare export type NavigationDescriptor = { - key: string, - state: NavigationRoute, - navigation: NavigationScreenProp<*>, - getComponent: () => React$ComponentType<{...}>, - ... - }; - - declare type NavigationView = React$ComponentType<{ - descriptors: { [key: string]: NavigationDescriptor, ... }, - navigation: NavigationScreenProp, - navigationConfig: *, - ... - }>; - - declare export function createNavigator( - view: NavigationView, - router: NavigationRouter, - navigatorConfig?: NavigatorConfig - ): NavigationNavigator; - - declare export function createStackNavigator( - routeConfigMap: NavigationRouteConfigMap, - stackConfig?: StackNavigatorConfig - ): NavigationNavigator<*, *, *>; - - declare type _TabViewConfig = {| - tabBarComponent?: React$ElementType, - tabBarPosition?: 'top' | 'bottom', - tabBarOptions?: {...}, - swipeEnabled?: boolean, - animationEnabled?: boolean, - configureTransition?: ( - currentTransitionProps: Object, - nextTransitionProps: Object - ) => Object, - initialLayout?: TabViewLayout, - |}; - declare type _TabNavigatorConfig = {| - ...NavigationTabRouterConfig, - ..._TabViewConfig, - lazy?: boolean, - removeClippedSubviews?: boolean, - containerOptions?: void, - |}; - /* TODO: fix the config for each of these tab navigator types */ - declare export function createBottomTabNavigator( - routeConfigs: NavigationRouteConfigMap, - config?: _TabNavigatorConfig - ): NavigationNavigator<*, *, *>; - declare export function createMaterialTopTabNavigator( - routeConfigs: NavigationRouteConfigMap, - config?: _TabNavigatorConfig - ): NavigationNavigator<*, *, *>; - declare type _SwitchNavigatorConfig = {| - ...NavigationSwitchRouterConfig, - |}; - declare export function createSwitchNavigator( - routeConfigs: NavigationRouteConfigMap, - config?: _SwitchNavigatorConfig - ): NavigationNavigator<*, *, *>; - - declare type _DrawerViewConfig = {| - drawerLockMode?: 'unlocked' | 'locked-closed' | 'locked-open', - drawerWidth?: number | (() => number), - drawerPosition?: 'left' | 'right', - contentComponent?: React$ElementType, - contentOptions?: {...}, - style?: ViewStyleProp, - useNativeAnimations?: boolean, - drawerBackgroundColor?: string, - overlayColor?: string, - screenProps?: {...}, - |}; - declare type _DrawerNavigatorConfig = $Exact<{ - ...NavigationTabRouterConfig, - ..._DrawerViewConfig, - containerConfig?: void, - ... - }>; - declare export function createDrawerNavigator( - routeConfigs: NavigationRouteConfigMap, - config?: _DrawerNavigatorConfig - ): NavigationNavigator<*, *, *>; - - declare export function StackRouter( - routeConfigs: NavigationRouteConfigMap, - stackConfig?: NavigationStackRouterConfig - ): NavigationRouter<*, NavigationStackScreenOptions>; - - declare export function TabRouter( - routeConfigs: NavigationRouteConfigMap, - config?: NavigationTabRouterConfig - ): NavigationRouter<*, *>; - - declare type _TransitionerProps = { - configureTransition: ( - transitionProps: NavigationTransitionProps, - prevTransitionProps: ?NavigationTransitionProps - ) => NavigationTransitionSpec, - navigation: NavigationScreenProp, - onTransitionEnd?: (...args: Array) => void, - onTransitionStart?: (...args: Array) => void, - render: ( - transitionProps: NavigationTransitionProps, - prevTransitionProps: ?NavigationTransitionProps - ) => React$Node, - ... - }; - declare export var Transitioner: React$ComponentType<_TransitionerProps>; - - declare type _CardStackTransitionerProps = { - headerMode: HeaderMode, - mode: 'card' | 'modal', - router: NavigationRouter, - cardStyle?: ViewStyleProp, - onTransitionStart?: () => void, - onTransitionEnd?: () => void, - /** - * Optional custom animation when transitioning between screens. - */ - transitionConfig?: () => TransitionConfig, - ... - } & NavigationNavigatorProps; - declare export var CardStackTransitioner: React$ComponentType< - _CardStackTransitionerProps - >; - - declare type _CardStackProps = { - screenProps?: {...}, - headerMode: HeaderMode, - headerComponent?: React$ElementType, - mode: 'card' | 'modal', - router: NavigationRouter, - cardStyle?: ViewStyleProp, - onTransitionStart?: () => void, - onTransitionEnd?: () => void, - /** - * Optional custom animation when transitioning between screens. - */ - transitionConfig?: () => TransitionConfig, - // NavigationTransitionProps: - layout: NavigationLayout, - navigation: NavigationScreenProp, - position: AnimatedValue, - progress: AnimatedValue, - scenes: Array, - scene: NavigationScene, - index: number, - ... - }; - declare export var CardStack: React$ComponentType<_CardStackProps>; - - declare type _CardProps = { - ...$Exact, - children: React$Node, - onComponentRef: React$Ref<*>, - pointerEvents: string, - style: any, - ... - }; - declare export var Card: React$ComponentType<_CardProps>; - - declare type _SafeAreaViewForceInsetValue = 'always' | 'never' | number; - declare type _SafeAreaViewInsets = $Shape<{ - top: _SafeAreaViewForceInsetValue, - bottom: _SafeAreaViewForceInsetValue, - left: _SafeAreaViewForceInsetValue, - right: _SafeAreaViewForceInsetValue, - vertical: _SafeAreaViewForceInsetValue, - horizontal: _SafeAreaViewForceInsetValue, - ... - }>; - declare type _SafeAreaViewProps = { - forceInset?: _SafeAreaViewInsets, - children?: React$Node, - style?: AnimatedViewStyleProp, - ... - }; - declare export var SafeAreaView: React$ComponentType<_SafeAreaViewProps>; - - declare export var Header: React$ComponentType & { HEIGHT: number, ... }; - - declare type _HeaderTitleProps = { - children: React$Node, - selectionColor?: string | number, - style?: AnimatedTextStyleProp, - ... - }; - declare export var HeaderTitle: React$ComponentType<_HeaderTitleProps>; - - declare type _HeaderBackButtonProps = { - onPress?: () => void, - pressColorAndroid?: string, - title?: ?string, - titleStyle?: ?TextStyleProp, - tintColor?: ?string, - truncatedTitle?: ?string, - width?: ?number, - ... - }; - declare export var HeaderBackButton: React$ComponentType< - _HeaderBackButtonProps - >; - - declare type _DrawerViewProps = { - drawerLockMode?: 'unlocked' | 'locked-closed' | 'locked-open', - drawerWidth: number | (() => number), - drawerPosition: 'left' | 'right', - contentComponent: React$ElementType, - contentOptions?: {...}, - style?: ViewStyleProp, - useNativeAnimations: boolean, - drawerBackgroundColor: string, - screenProps?: {...}, - navigation: NavigationScreenProp, - router: NavigationRouter, - ... - }; - declare export var DrawerView: React$ComponentType<_DrawerViewProps>; - - declare type _DrawerScene = { - route: NavigationRoute, - focused: boolean, - index: number, - tintColor?: string, - ... - }; - declare type _DrawerItem = { - route: NavigationRoute, - focused: boolean, - ... - }; - declare type _DrawerItemsProps = { - navigation: NavigationScreenProp, - items: Array, - activeItemKey?: ?string, - activeTintColor?: string, - activeBackgroundColor?: string, - inactiveTintColor?: string, - inactiveBackgroundColor?: string, - getLabel: (scene: _DrawerScene) => ?(React$Node | string), - renderIcon: (scene: _DrawerScene) => ?React$Node, - onItemPress: (info: _DrawerItem) => void, - itemsContainerForceInset?: Object, - itemsContainerStyle?: ViewStyleProp, - itemStyle?: ViewStyleProp, - labelStyle?: TextStyleProp, - activeLabelStyle?: TextStyleProp, - inactiveLabelStyle?: TextStyleProp, - iconContainerStyle?: ViewStyleProp, - drawerPosition: 'left' | 'right', - ... - }; - declare export var DrawerItems: React$ComponentType<_DrawerItemsProps>; - - declare type _TabViewProps = { - tabBarComponent?: React$ElementType, - tabBarPosition?: 'top' | 'bottom', - tabBarOptions?: {...}, - swipeEnabled?: boolean, - animationEnabled?: boolean, - configureTransition?: ( - currentTransitionProps: Object, - nextTransitionProps: Object - ) => Object, - initialLayout: TabViewLayout, - screenProps?: {...}, - navigation: NavigationScreenProp, - router: NavigationRouter, - ... - }; - declare export var TabView: React$ComponentType<_TabViewProps>; - - declare type _MaterialTopTabBarProps = { - activeTintColor: string, - inactiveTintColor: string, - showIcon: boolean, - showLabel: boolean, - upperCaseLabel: boolean, - allowFontScaling: boolean, - position: AnimatedValue, - tabBarPosition: string, - navigation: NavigationScreenProp, - jumpToIndex: (index: number) => void, - getLabel: (scene: TabScene) => ?(React$Node | string), - getOnPress: ( - previousScene: NavigationRoute, - scene: TabScene - ) => ({ - previousScene: NavigationRoute, - scene: TabScene, - jumpToIndex: (index: number) => void, - ... - }) => void, - renderIcon: (scene: TabScene) => React$Element<*>, - labelStyle?: TextStyleProp, - iconStyle?: ViewStyleProp, - ... - }; - declare export var MaterialTopTabBar: React$ComponentType< - _MaterialTopTabBarProps - >; - - declare type _BottomTabBarButtonComponentProps = { - onPress: () => void, - onLongPress: () => void, - testID: string, - accessibilityLabel: string, - style: ViewStyleProp, - ... - }; - declare type _BottomTabBarProps = { - activeTintColor: string, - activeBackgroundColor: string, - adaptive?: boolean, - inactiveTintColor: string, - inactiveBackgroundColor: string, - showLabel: boolean, - showIcon: boolean, - allowFontScaling: boolean, - position: AnimatedValue, - navigation: NavigationScreenProp, - jumpToIndex: (index: number) => void, - getLabel: (scene: TabScene) => ?(React$Node | string), - getOnPress: ( - previousScene: NavigationRoute, - scene: TabScene - ) => ({ - previousScene: NavigationRoute, - scene: TabScene, - jumpToIndex: (index: number) => void, - ... - }) => void, - getTestIDProps: (scene: TabScene) => (scene: TabScene) => any, - renderIcon: (scene: TabScene) => React$Node, - getButtonComponent: ( - scene: TabScene - ) => React$ComponentType<_BottomTabBarButtonComponentProps>, - style?: ViewStyleProp, - animateStyle?: ViewStyleProp, - labelStyle?: TextStyleProp, - tabStyle?: ViewStyleProp, - showIcon?: boolean, - ... - }; - declare export var BottomTabBar: React$ComponentType<_BottomTabBarProps>; - - declare export function withNavigation>( - Component: ComponentType - ): React$ComponentType< - $Diff< - React$ElementConfig, - { navigation: NavigationScreenProp | void, ... } - > - >; - declare export function withNavigationFocus>( - Component: ComponentType - ): React$ComponentType<$Diff, { isFocused: boolean | void, ... }>>; - - declare export function getNavigation( - router: NavigationRouter, - state: State, - dispatch: NavigationDispatch, - actionSubscribers: Set, - getScreenProps: () => {...}, - getCurrentNavigation: () => ?NavigationScreenProp - ): NavigationScreenProp; - - declare export function getActiveChildNavigationOptions< - State: NavigationState, - Options: {...} - >( - navigation: NavigationScreenProp, - screenProps?: {...} - ): Options; -} diff --git a/flow-typed/npm/react-navigation_v4.x.x.js b/flow-typed/npm/react-navigation_v4.x.x.js new file mode 100644 index 00000000000..5ab816be1b5 --- /dev/null +++ b/flow-typed/npm/react-navigation_v4.x.x.js @@ -0,0 +1,980 @@ +// flow-typed signature: 2f68f3597d70aadb9da3fb85b4193dc0 +// flow-typed version: ab8203bb4a/react-navigation_v4.x.x/flow_>=v0.104.x + +// @flow + +declare module 'react-navigation' { + + //--------------------------------------------------------------------------- + // SECTION 1: IDENTICAL TYPE DEFINITIONS + // This section is identical across all React Navigation libdefs and contains + // shared definitions. We wish we could make it DRY and import from a shared + // definition, but that isn't yet possible. + //--------------------------------------------------------------------------- + + /** + * SECTION 1A + * We start with some definitions that we have copy-pasted from React Native + * source files. + */ + + // This is a bastardization of the true StyleObj type located in + // react-native/Libraries/StyleSheet/StyleSheetTypes. We unfortunately can't + // import that here, and it's too lengthy (and consequently too brittle) to + // copy-paste here either. + declare type StyleObj = + | null + | void + | number + | false + | '' + | $ReadOnlyArray + | { [name: string]: any, ... }; + declare type ViewStyleProp = StyleObj; + declare type TextStyleProp = StyleObj; + declare type AnimatedViewStyleProp = StyleObj; + declare type AnimatedTextStyleProp = StyleObj; + + /** + * SECTION 1B + * The following are type declarations for core types necessary for every + * React Navigation libdef. + */ + + /** + * Navigation State + Action + */ + + declare export type NavigationParams = { [key: string]: mixed, ... }; + + declare export type NavigationBackAction = {| + type: 'Navigation/BACK', + key?: ?string, + |}; + declare export type NavigationInitAction = {| + type: 'Navigation/INIT', + params?: NavigationParams, + |}; + declare export type NavigationNavigateAction = {| + type: 'Navigation/NAVIGATE', + routeName: string, + params?: NavigationParams, + + // The action to run inside the sub-router + action?: NavigationNavigateAction, + + key?: string, + |}; + declare export type NavigationSetParamsAction = {| + type: 'Navigation/SET_PARAMS', + + // The key of the route where the params should be set + key: string, + + // The new params to merge into the existing route params + params: NavigationParams, + |}; + + declare export type NavigationPopAction = {| + +type: 'Navigation/POP', + +n?: number, + +immediate?: boolean, + |}; + declare export type NavigationPopToTopAction = {| + +type: 'Navigation/POP_TO_TOP', + +immediate?: boolean, + |}; + declare export type NavigationPushAction = {| + +type: 'Navigation/PUSH', + +routeName: string, + +params?: NavigationParams, + +action?: NavigationNavigateAction, + +key?: string, + |}; + declare export type NavigationResetAction = {| + type: 'Navigation/RESET', + index: number, + key?: ?string, + actions: Array, + |}; + declare export type NavigationReplaceAction = {| + +type: 'Navigation/REPLACE', + +key: string, + +routeName: string, + +params?: NavigationParams, + +action?: NavigationNavigateAction, + |}; + declare export type NavigationCompleteTransitionAction = {| + +type: 'Navigation/COMPLETE_TRANSITION', + +key?: string, + +toChildKey?: string, + |}; + + declare export type NavigationOpenDrawerAction = {| + +type: 'Navigation/OPEN_DRAWER', + +key?: string, + |}; + declare export type NavigationCloseDrawerAction = {| + +type: 'Navigation/CLOSE_DRAWER', + +key?: string, + |}; + declare export type NavigationToggleDrawerAction = {| + +type: 'Navigation/TOGGLE_DRAWER', + +key?: string, + |}; + declare export type NavigationDrawerOpenedAction = {| + +type: 'Navigation/DRAWER_OPENED', + +key?: string, + |}; + declare export type NavigationDrawerClosedAction = {| + +type: 'Navigation/DRAWER_CLOSED', + +key?: string, + |}; + + declare export type NavigationJumpToAction = {| + +type: 'Navigation/JUMP_TO'; + +preserveFocus: boolean, + +routeName: string, + +key?: string, + +params?: NavigationParams, + |}; + + declare export type NavigationAction = + | NavigationBackAction + | NavigationInitAction + | NavigationNavigateAction + | NavigationSetParamsAction + | NavigationPopAction + | NavigationPopToTopAction + | NavigationPushAction + | NavigationResetAction + | NavigationReplaceAction + | NavigationCompleteTransitionAction + | NavigationOpenDrawerAction + | NavigationCloseDrawerAction + | NavigationToggleDrawerAction + | NavigationDrawerOpenedAction + | NavigationDrawerClosedAction + | NavigationJumpToAction; + + /** + * NavigationState is a tree of routes for a single navigator, where each + * child route may either be a NavigationScreenRoute or a + * NavigationRouterRoute. NavigationScreenRoute represents a leaf screen, + * while the NavigationRouterRoute represents the state of a child navigator. + * + * NOTE: NavigationState is a state tree local to a single navigator and + * its child navigators (via the routes field). + * If we're in navigator nested deep inside the app, the state will only be + * the state for that navigator. + * The state for the root navigator of our app represents the whole navigation + * state for the whole app. + */ + declare export type NavigationState = { + /** + * Index refers to the active child route in the routes array. + */ + index: number, + routes: Array, + isTransitioning?: bool, + ... + }; + + declare export type NavigationRoute = + | NavigationLeafRoute + | NavigationStateRoute; + + declare export type NavigationLeafRoute = {| + /** + * React's key used by some navigators. No need to specify these manually, + * they will be defined by the router. + */ + key: string, + /** + * For example 'Home'. + * This is used as a key in a route config when creating a navigator. + */ + routeName: string, + /** + * Path is an advanced feature used for deep linking and on the web. + */ + path?: string, + /** + * Params passed to this route when navigating to it, + * e.g. `{ car_id: 123 }` in a route that displays a car. + */ + params?: NavigationParams, + |}; + + declare export type NavigationStateRoute = {| + ...NavigationLeafRoute, + ...$Exact, + |}; + + /** + * Router + */ + + declare export type NavigationScreenProps = { [key: string]: mixed, ... }; + + declare export type NavigationScreenOptionsGetter = ( + navigation: NavigationScreenProp, + screenProps: ?NavigationScreenProps, + theme: SupportedThemes, + ) => Options; + + declare export type NavigationRouter = { + /** + * The reducer that outputs the new navigation state for a given action, + * with an optional previous state. When the action is considered handled + * but the state is unchanged, the output state is null. + */ + getStateForAction: (action: NavigationAction, lastState: ?State) => ?State, + /** + * Maps a URI-like string to an action. This can be mapped to a state + * using `getStateForAction`. + */ + getActionForPathAndParams: ( + path: string, + params?: NavigationParams + ) => ?NavigationAction, + getPathAndParamsForState: ( + state: State + ) => { + path: string, + params?: NavigationParams, + ... + }, + getComponentForRouteName: (routeName: string) => NavigationComponent, + getComponentForState: (state: State) => NavigationComponent, + /** + * Gets the screen navigation options for a given screen. + * + * For example, we could get the config for the 'Foo' screen when the + * `navigation.state` is: + * + * {routeName: 'Foo', key: '123'} + */ + getScreenOptions: NavigationScreenOptionsGetter, + ... + }; + + declare export type NavigationScreenOptions = { title?: string, ... }; + + declare export type SupportedThemes = 'light' | 'dark'; + + declare export type NavigationScreenConfigProps = $Shape<{| + navigation: NavigationScreenProp, + screenProps: NavigationScreenProps, + theme: SupportedThemes, + |}>; + + declare export type NavigationScreenConfig = + | Options + | (({| + ...NavigationScreenConfigProps, + navigationOptions: Options, + |}) => Options); + + declare export type NavigationComponent = + | NavigationScreenComponent + | NavigationNavigator<*, *, *>; + + declare interface withOptionalNavigationOptions { + navigationOptions?: NavigationScreenConfig; + } + + declare export type NavigationScreenComponent< + Route: NavigationRoute, + Options: {...}, + Props: NavigationNavigatorProps, + > = React$ComponentType & + withOptionalNavigationOptions; + + declare interface withRouter { + router: NavigationRouter; + } + + declare export type NavigationNavigator< + State: NavigationState, + Options: {...}, + Props: NavigationNavigatorProps, + > = React$ComponentType & + withRouter & + withOptionalNavigationOptions; + + declare type _NavigationRouteConfigCore = {| + navigationOptions?: NavigationScreenConfig<*>, + params?: NavigationParams, + path?: string, + |}; + declare export type NavigationRouteConfig = + | NavigationComponent + | {| ..._NavigationRouteConfigCore, screen: NavigationComponent |} + | {| ..._NavigationRouteConfigCore, getScreen: () => NavigationComponent |}; + + declare export type NavigationRouteConfigMap = { [routeName: string]: NavigationRouteConfig, ... }; + + /** + * Navigator Prop + */ + + declare export type NavigationDispatch = ( + action: NavigationAction + ) => boolean; + + declare export type EventType = + | 'willFocus' + | 'didFocus' + | 'willBlur' + | 'didBlur' + | 'action'; + + declare export type NavigationEventPayload = {| + type: EventType, + action: NavigationAction, + state: NavigationState, + lastState: ?NavigationState, + |}; + + declare export type NavigationEventCallback = ( + payload: NavigationEventPayload + ) => void; + + declare export type NavigationEventSubscription = {| remove: () => void |}; + + declare export type NavigationScreenProp<+S> = { + +state: S, + dispatch: NavigationDispatch, + addListener: ( + eventName: string, + callback: NavigationEventCallback + ) => NavigationEventSubscription, + getParam: ( + paramName: ParamName, + fallback?: $ElementType< + $PropertyType< + {| + ...{| params: {...} |}, + ...$Exact, + |}, + 'params' + >, + ParamName + > + ) => $ElementType< + $PropertyType< + {| + ...{| params: {...} |}, + ...$Exact, + |}, + 'params' + >, + ParamName + >, + dangerouslyGetParent: () => ?NavigationScreenProp, + isFocused: () => boolean, + goBack: (routeKey?: ?string) => boolean, + dismiss: () => boolean, + navigate: ( + routeName: + | string + | { + routeName: string, + params?: NavigationParams, + action?: NavigationNavigateAction, + key?: string, + ... + }, + params?: NavigationParams, + action?: NavigationNavigateAction + ) => boolean, + setParams: (newParams: NavigationParams) => boolean, + ... + }; + + declare export type NavigationNavigatorProps = $Shape<{ + navigation: NavigationScreenProp, + screenProps?: NavigationScreenProps, + navigationOptions?: O, + theme?: SupportedThemes | 'no-preference', + detached?: boolean, + ... + }>; + + /** + * Navigation container + */ + + declare export type NavigationContainer< + State: NavigationState, + Options: {...}, + Props: NavigationContainerProps, + > = React$ComponentType & + withRouter & + withOptionalNavigationOptions; + + declare export type NavigationContainerProps = $Shape<{ + uriPrefix?: string | RegExp, + onNavigationStateChange?: ?( + NavigationState, + NavigationState, + NavigationAction + ) => void, + navigation?: NavigationScreenProp, + persistenceKey?: ?string, + renderLoadingExperimental?: React$ComponentType<{...}>, + screenProps?: NavigationScreenProps, + navigationOptions?: O, + ... + }>; + + /** + * NavigationDescriptor + */ + + declare export type NavigationDescriptor = { + key: string, + state: NavigationRoute, + navigation: NavigationScreenProp, + getComponent: () => NavigationComponent, + ... + }; + + declare export type NavigationDescriptorMap = { + [key: string]: NavigationDescriptor, + ... + }; + + //--------------------------------------------------------------------------- + // SECTION 2: SHARED TYPE DEFINITIONS + // This section too is copy-pasted, but it's not identical across all React + // Navigation libdefs. We pick out bits and pieces that we need. + //--------------------------------------------------------------------------- + + /** + * SECTION 2A + * We start with definitions we have copy-pasted, either from in-package + * types, other Flow libdefs, or from TypeScript types somewhere. + */ + + // This is copied from + // react-native/Libraries/Animated/src/nodes/AnimatedInterpolation.js + declare type ExtrapolateType = 'extend' | 'identity' | 'clamp'; + declare type InterpolationConfigType = { + inputRange: Array, + outputRange: Array | Array, + easing?: (input: number) => number, + extrapolate?: ExtrapolateType, + extrapolateLeft?: ExtrapolateType, + extrapolateRight?: ExtrapolateType, + ... + }; + declare class AnimatedInterpolation { + interpolate(config: InterpolationConfigType): AnimatedInterpolation; + } + + // This is copied from + // react-native/Libraries/Animated/src/animations/Animation.js + declare type EndResult = { finished: boolean, ... }; + declare type EndCallback = (result: EndResult) => void; + declare class Animation { + start( + fromValue: number, + onUpdate: (value: number) => void, + onEnd: ?EndCallback, + previousAnimation: ?Animation, + animatedValue: AnimatedValue, + ): void; + stop(): void; + } + + // This is vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedTracking.js + declare class AnimatedTracking { + constructor( + value: AnimatedValue, + parent: any, + animationClass: any, + animationConfig: Object, + callback?: ?EndCallback, + ): void; + update(): void; + } + + // This is vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedValue.js + declare type ValueListenerCallback = (state: { value: number, ... }) => void; + declare class AnimatedValue { + constructor(value: number): void; + setValue(value: number): void; + setOffset(offset: number): void; + flattenOffset(): void; + extractOffset(): void; + addListener(callback: ValueListenerCallback): string; + removeListener(id: string): void; + removeAllListeners(): void; + stopAnimation(callback?: ?(value: number) => void): void; + resetAnimation(callback?: ?(value: number) => void): void; + interpolate(config: InterpolationConfigType): AnimatedInterpolation; + animate(animation: Animation, callback: ?EndCallback): void; + stopTracking(): void; + track(tracking: AnimatedTracking): void; + } + + /** + * SECTION 2B + * The following are the actually useful definitions in Section 2, that are + * used below in section 3, but also in other libdefs. + */ + + declare export type NavigationPathsConfig = { [routeName: string]: string, ... }; + + /** + * SafeAreaView + */ + + declare type _SafeAreaViewForceInsetValue = 'always' | 'never' | number; + declare type _SafeAreaViewInsets = $Shape<{| + top: _SafeAreaViewForceInsetValue, + bottom: _SafeAreaViewForceInsetValue, + left: _SafeAreaViewForceInsetValue, + right: _SafeAreaViewForceInsetValue, + vertical: _SafeAreaViewForceInsetValue, + horizontal: _SafeAreaViewForceInsetValue, + |}>; + + /** + * Interpolation + */ + + declare export type NavigationStackInterpolatorProps = $Shape<{| + layout: NavigationStackLayout, + scene: NavigationStackScene, + scenes: NavigationStackScene[], + position: AnimatedInterpolation, + navigation: NavigationStackProp, + mode?: HeaderMode, + shadowEnabled?: boolean, + cardOverlayEnabled?: boolean, + |}>; + + declare type _InterpolationResult = { [key: string]: mixed, ... }; + declare export type NavigationStackInterpolator = + (props: NavigationStackInterpolatorProps) => _InterpolationResult; + + /** + * Header + */ + + declare export type HeaderMode = 'float' | 'screen' | 'none'; + + declare export type HeaderProps = {| + layout: NavigationStackLayout, + scene: NavigationStackScene, + scenes: NavigationStackScene[], + position: AnimatedInterpolation, + navigation: NavigationStackProp, + mode: HeaderMode, + leftInterpolator?: NavigationStackInterpolator, + titleInterpolator?: NavigationStackInterpolator, + rightInterpolator?: NavigationStackInterpolator, + backgroundInterpolator?: NavigationStackInterpolator, + layoutPreset: 'left' | 'center', + transitionPreset?: 'fade-in-place' | 'uikit', + backTitleVisible?: boolean, + isLandscape: boolean, + |}; + + /** + * StackRouter + */ + + declare export type NavigationStackProp<+S> = + & NavigationScreenProp + & { + pop: (n?: number, params?: {| immediate?: boolean |}) => boolean, + popToTop: (params?: {| immediate?: boolean |}) => boolean, + push: ( + routeName: string, + params?: NavigationParams, + action?: NavigationNavigateAction + ) => boolean, + replace: ( + routeName: string, + params?: NavigationParams, + action?: NavigationNavigateAction + ) => boolean, + reset: (actions: NavigationAction[], index: number) => boolean, + ... + }; + + declare type _HeaderBackButtonProps = {| + disabled?: boolean, + onPress: () => void, + pressColorAndroid?: string, + tintColor?: ?string, + backImage?: React$ComponentType<{ + tintColor: string, + title?: ?string, + ... + }>, + title?: ?string, + truncatedTitle?: ?string, + backTitleVisible?: boolean, + allowFontScaling?: boolean, + titleStyle?: ?TextStyleProp, + headerLayoutPreset: 'left' | 'center', + width?: ?number, + scene: NavigationStackScene, + |}; + + declare export type NavigationStackScreenOptions = NavigationScreenOptions & { + header?: ?(React$Node | (HeaderProps => React$Node)), + headerTransparent?: boolean, + headerTitle?: (props: { children: ?string, ... }) => React$Node | React$Node, + headerTitleStyle?: AnimatedTextStyleProp, + headerTitleAllowFontScaling?: boolean, + headerTintColor?: string, + headerLeft?: ((props: _HeaderBackButtonProps) => React$Node) | React$Node, + headerBackTitle?: ?string, + headerBackImage?: (props: {| + tintColor?: string, + title?: ?string, + |}) => React$Node, + headerTruncatedBackTitle?: string, + headerBackTitleStyle?: TextStyleProp, + headerPressColorAndroid?: string, + headerRight?: React$Node, + headerStyle?: ViewStyleProp, + headerForceInset?: _SafeAreaViewInsets, + headerBackground?: React$Node | React$ElementType, + gesturesEnabled?: boolean, + gestureResponseDistance?: {| + vertical?: number, + horizontal?: number, + |}, + gestureDirection?: 'default' | 'inverted', + ... + }; + + declare export type NavigationStackRouterConfig = {| + initialRouteName?: string, + initialRouteParams?: NavigationParams, + paths?: NavigationPathsConfig, + navigationOptions?: NavigationScreenConfig<*>, + defaultNavigationOptions?: NavigationScreenConfig<*>, + initialRouteKey?: string, + |}; + + /** + * Stack Gestures, Animations, and Interpolators + */ + + declare export type NavigationStackLayout = { + height: AnimatedValue, + initHeight: number, + initWidth: number, + isMeasured: boolean, + width: AnimatedValue, + ... + }; + + declare export type NavigationStackScene = { + index: number, + isActive: boolean, + isStale: boolean, + key: string, + route: NavigationRoute, + descriptor: ?NavigationDescriptor, + ... + }; + + /** + * SwitchRouter + */ + + declare export type NavigationSwitchRouterConfig = {| + initialRouteName?: string, + initialRouteParams?: NavigationParams, + paths?: NavigationPathsConfig, + navigationOptions?: NavigationScreenConfig<*>, + defaultNavigationOptions?: NavigationScreenConfig<*>, + // todo: type these as the real route names rather than 'string' + order?: string[], + // Does the back button cause the router to switch to the initial tab + backBehavior?: 'none' | 'initialRoute' | 'history' | 'order', // defaults `initialRoute` + resetOnBlur?: boolean, + |}; + + /** + * TabRouter + */ + + declare export type NavigationTabProp<+S> = + & NavigationScreenProp + & { jumpTo: (routeName: string, key?: string) => void, ... }; + + declare export type NavigationTabRouterConfig = NavigationSwitchRouterConfig; + + declare export type NavigationTabScreenOptions = { + ...$Exact, + tabBarLabel?: React$Node, + tabBarVisible?: boolean, + tabBarAccessibilityLabel?: string, + tabBarTestID?: string, + tabBarIcon?: + | React$Node + | ((props: {| + focused: boolean, + tintColor?: string, + horizontal?: boolean, + |}) => React$Node), + tabBarOnPress?: (props: {| + navigation: NavigationTabProp, + defaultHandler: () => void, + |}) => void, + tabBarOnLongPress?: (props: {| + navigation: NavigationTabProp, + defaultHandler: () => void, + |}) => void, + ... + }; + + //--------------------------------------------------------------------------- + // SECTION 3: UNIQUE TYPE DEFINITIONS + // This section normally contains exported types that are not present in any + // other React Navigation libdef. But the main react-navigation libdef doesn't + // have any, so it's empty here. + //--------------------------------------------------------------------------- + + //--------------------------------------------------------------------------- + // SECTION 4: EXPORTED MODULE + // This is the only section that types exports. Other sections export types, + // but this section types the module's exports. + //--------------------------------------------------------------------------- + + declare export var StateUtils: { + get: (state: NavigationState, key: string) => ?NavigationRoute, + indexOf: (state: NavigationState, key: string) => number, + has: (state: NavigationState, key: string) => boolean, + push: (state: NavigationState, route: NavigationRoute) => NavigationState, + pop: (state: NavigationState) => NavigationState, + jumpToIndex: (state: NavigationState, index: number) => NavigationState, + jumpTo: (state: NavigationState, key: string) => NavigationState, + back: (state: NavigationState) => NavigationState, + forward: (state: NavigationState) => NavigationState, + replaceAt: ( + state: NavigationState, + key: string, + route: NavigationRoute + ) => NavigationState, + replaceAtIndex: ( + state: NavigationState, + index: number, + route: NavigationRoute + ) => NavigationState, + reset: ( + state: NavigationState, + routes: Array, + index?: number + ) => NavigationState, + ... + }; + + declare export function getNavigation( + router: NavigationRouter, + state: State, + dispatch: NavigationDispatch, + actionSubscribers: Set, + getScreenProps: () => {...}, + getCurrentNavigation: () => ?NavigationScreenProp + ): NavigationScreenProp; + + declare type _NavigationView> = React$ComponentType<{ + descriptors: NavigationDescriptorMap, + navigation: N, + navigationConfig: *, + ... + }>; + declare export function createNavigator>( + view: _NavigationView, + router: NavigationRouter, + navigatorConfig?: NavigatorConfig + ): NavigationNavigator; + + declare export var NavigationContext: React$Context< + ?NavigationScreenProp, + >; + declare export var NavigationProvider: $PropertyType; + declare export var NavigationConsumer: $PropertyType; + + declare type _SwitchNavigatorConfig = NavigationSwitchRouterConfig; + declare export function createSwitchNavigator( + routeConfigs: NavigationRouteConfigMap, + config?: _SwitchNavigatorConfig + ): NavigationNavigator<*, *, *>; + + declare export var ThemeContext: React$Context; + declare export var ThemeProvider: $PropertyType; + declare export var ThemeConsumer: $PropertyType; + declare export var ThemeColors: { [theme: SupportedThemes]: { [key: string]: string, ... }, ... }; + declare export function useTheme(): SupportedThemes; + + declare export var NavigationActions: {| + BACK: 'Navigation/BACK', + INIT: 'Navigation/INIT', + NAVIGATE: 'Navigation/NAVIGATE', + SET_PARAMS: 'Navigation/SET_PARAMS', + back: (payload?: {| key?: ?string |}) => NavigationBackAction, + init: (payload?: {| params?: NavigationParams |}) => NavigationInitAction, + navigate: (payload: {| + routeName: string, + params?: ?NavigationParams, + action?: ?NavigationNavigateAction, + key?: string, + |}) => NavigationNavigateAction, + setParams: (payload: {| + key: string, + params: NavigationParams, + |}) => NavigationSetParamsAction, + |}; + + declare export var StackActions: {| + POP: 'Navigation/POP', + POP_TO_TOP: 'Navigation/POP_TO_TOP', + PUSH: 'Navigation/PUSH', + RESET: 'Navigation/RESET', + REPLACE: 'Navigation/REPLACE', + COMPLETE_TRANSITION: 'Navigation/COMPLETE_TRANSITION', + pop: (payload: {| + n?: number, + immediate?: boolean, + |}) => NavigationPopAction, + popToTop: (payload: {| immediate?: boolean |}) => NavigationPopToTopAction, + push: (payload: {| + routeName: string, + params?: NavigationParams, + action?: NavigationNavigateAction, + key?: string, + |}) => NavigationPushAction, + reset: (payload: {| + index: number, + key?: ?string, + actions: Array, + |}) => NavigationResetAction, + replace: (payload: {| + key?: string, + routeName: string, + params?: NavigationParams, + action?: NavigationNavigateAction, + |}) => NavigationReplaceAction, + completeTransition: (payload: {| + key?: string, + toChildKey?: string, + |}) => NavigationCompleteTransitionAction, + |}; + + declare export var SwitchActions: {| + JUMP_TO: 'Navigation/JUMP_TO', + jumpTo: (payload: {| + routeName: string, + key?: string, + params?: NavigationParams, + |}) => NavigationJumpToAction, + |}; + + declare export function StackRouter( + routeConfigs: NavigationRouteConfigMap, + stackConfig?: NavigationStackRouterConfig + ): NavigationRouter<*, NavigationStackScreenOptions>; + + declare export function TabRouter( + routeConfigs: NavigationRouteConfigMap, + config?: NavigationTabRouterConfig + ): NavigationRouter<*, NavigationTabScreenOptions>; + + declare export function SwitchRouter( + routeConfigs: NavigationRouteConfigMap, + stackConfig?: NavigationSwitchRouterConfig + ): NavigationRouter<*, {| |}>; + + declare export function getActiveChildNavigationOptions< + State: NavigationState, + Options: {...} + >( + navigation: NavigationScreenProp, + screenProps?: NavigationScreenProps, + theme?: SupportedThemes, + ): Options; + + declare type _SceneViewProps = { + component: React$ComponentType<{ + screenProps: ?NavigationScreenProps, + navigation: NavigationScreenProp, + ... + }>, + screenProps: ?NavigationScreenProps, + navigation: NavigationScreenProp, + ... + }; + declare export var SceneView: React$ComponentType<_SceneViewProps>; + + declare type _NavigationEventsProps = { + navigation?: NavigationScreenProp, + onWillFocus?: NavigationEventCallback, + onDidFocus?: NavigationEventCallback, + onWillBlur?: NavigationEventCallback, + onDidBlur?: NavigationEventCallback, + ... + }; + declare export var NavigationEvents: React$ComponentType< + _NavigationEventsProps + >; + + declare export function withNavigation>( + Component: ComponentType + ): React$ComponentType< + $Diff< + React$ElementConfig, + {| navigation: NavigationScreenProp |} + > + >; + declare export function withNavigationFocus>( + Component: ComponentType + ): React$ComponentType<$Diff, {| isFocused: ?boolean |}>>; + + declare export function createAppContainer( + Component: NavigationNavigator + ): NavigationContainer; + + declare export function createKeyboardAwareNavigator( + Comp: React$ComponentType, + stackConfig: {...} + ): React$ComponentType; + + declare export function withOrientation>( + Component: ComponentType + ): React$ComponentType<$Diff, {| isLandscape: boolean |}>>; + + declare type _SafeAreaViewProps = { + forceInset?: _SafeAreaViewInsets, + children?: React$Node, + style?: AnimatedViewStyleProp, + ... + }; + declare export var SafeAreaView: React$ComponentType<_SafeAreaViewProps>; + + // These components take the same props that their React Native primitives do + // Typing them correctly would be extremely brittle + // We await the day we can import types from libraries in flow-typed libdefs + declare export var ScrollView: React$ComponentType<{...}>; + declare export var FlatList: React$ComponentType<{...}>; + declare export var SectionList: React$ComponentType<{...}>; + declare export var Themed: {| + StatusBar: React$ComponentType<{...}>, + Text: React$ComponentType<{...}>, + TextInput: React$ComponentType<{...}>, + |}; + +} diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 8026c824c65..280eac8b7b9 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -275,6 +275,8 @@ PODS: - React - react-native-safe-area (0.4.4): - React + - react-native-safe-area-context (3.1.7): + - React - react-native-simple-toast (1.0.0): - React - Toast (~> 4.0.0) @@ -321,10 +323,14 @@ PODS: - React-Core - RNCAsyncStorage (1.6.3): - React + - RNCMaskedView (0.1.10): + - React - RNDeviceInfo (0.21.5): - React - RNGestureHandler (1.8.0): - React + - RNReanimated (1.13.0): + - React - RNSentry (1.6.3): - React - Sentry (~> 5.1.8) @@ -410,6 +416,7 @@ DEPENDENCIES: - 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`) + - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - react-native-simple-toast (from `../node_modules/react-native-simple-toast`) - react-native-webview (from `../node_modules/react-native-webview`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) @@ -426,8 +433,10 @@ DEPENDENCIES: - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - rn-fetch-blob (from `../node_modules/rn-fetch-blob`) - "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)" + - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)" - RNDeviceInfo (from `../node_modules/react-native-device-info`) - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) + - RNReanimated (from `../node_modules/react-native-reanimated`) - "RNSentry (from `../node_modules/@sentry/react-native`)" - RNSound (from `../node_modules/react-native-sound`) - RNVectorIcons (from `../node_modules/react-native-vector-icons`) @@ -520,6 +529,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-safari-view" react-native-safe-area: :path: "../node_modules/react-native-safe-area" + react-native-safe-area-context: + :path: "../node_modules/react-native-safe-area-context" react-native-simple-toast: :path: "../node_modules/react-native-simple-toast" react-native-webview: @@ -550,10 +561,14 @@ EXTERNAL SOURCES: :path: "../node_modules/rn-fetch-blob" RNCAsyncStorage: :path: "../node_modules/@react-native-community/async-storage" + RNCMaskedView: + :path: "../node_modules/@react-native-community/masked-view" RNDeviceInfo: :path: "../node_modules/react-native-device-info" RNGestureHandler: :path: "../node_modules/react-native-gesture-handler" + RNReanimated: + :path: "../node_modules/react-native-reanimated" RNSentry: :path: "../node_modules/@sentry/react-native" RNSound: @@ -629,6 +644,7 @@ SPEC CHECKSUMS: react-native-photo-view: 63e9e61da873531f931008b545d8d10c5373ddf8 react-native-safari-view: 955d7160d159241b8e9395d12d10ea0ef863dcdd react-native-safe-area: 5fce5242419932bc05656f31bc5f0716e30be0f6 + react-native-safe-area-context: 955ecfce672683b495d9294d2f154a9ad1d9796b react-native-simple-toast: 6c376bd79b1e255a4bee90a72ead6447f96ea10d react-native-webview: 83d00afd3f3ebfbee7f02d149ce1bfa8494d55f3 React-RCTActionSheet: 600b4d10e3aea0913b5a92256d2719c0cdd26d76 @@ -644,8 +660,10 @@ SPEC CHECKSUMS: ReactCommon: 198c7c8d3591f975e5431bec1b0b3b581aa1c5dd rn-fetch-blob: f525a73a78df9ed5d35e67ea65e79d53c15255bc RNCAsyncStorage: 3c304d1adfaea02ec732ac218801cb13897aa8c0 + RNCMaskedView: 5a8ec07677aa885546a0d98da336457e2bea557f RNDeviceInfo: e7c5fcde13d40e161d8a27f6c5dc69c638936002 RNGestureHandler: 7a5833d0f788dbd107fbb913e09aa0c1ff333c39 + RNReanimated: 89f5e0a04d1dd52fbf27e7e7030d8f80a646a3fc RNSentry: ae1e005e4f2655775475445a9c49c1d343e8e3a7 RNSound: da030221e6ac7e8290c6b43f2b5f2133a8e225b0 RNVectorIcons: 0bb4def82230be1333ddaeee9fcba45f0b288ed4 diff --git a/jest/jestSetup.js b/jest/jestSetup.js index 0a4f052d8c0..1d438e79619 100644 --- a/jest/jestSetup.js +++ b/jest/jestSetup.js @@ -53,6 +53,18 @@ jest.mock('react-native', () => { * before mocking it here. */ +// As instructed at https://reactnavigation.org/docs/testing/. +jest.mock('react-native-reanimated', () => { + /* eslint-disable-next-line global-require */ + const Reanimated = require('react-native-reanimated/mock'); + + // The mock for `call` immediately calls the callback which is incorrect + // So we override it with a no-op + Reanimated.default.call = () => {}; + + return Reanimated; +}); + jest.mock('@react-native-community/async-storage', () => mockAsyncStorage); jest.mock('react-native-sound', () => () => ({ diff --git a/package.json b/package.json index 89d53567f25..b5f90b141b0 100644 --- a/package.json +++ b/package.json @@ -34,9 +34,9 @@ "@expo/react-native-action-sheet": "^3.4.0", "@react-native-community/async-storage": "^1.6.3", "@react-native-community/cameraroll": "^1.7.2", + "@react-native-community/masked-view": "^0.1.10", "@react-native-community/netinfo": "^5.9.5", - "@react-navigation/core": "^3.5.0", - "@react-navigation/native": "^3.6.2", + "@react-navigation/core": "^3.7.6", "@sentry/react-native": "^1.0.9", "@unimodules/core": "~5.1.2", "@zulip/shared": "^0.0.2", @@ -66,9 +66,11 @@ "react-native-image-picker": "^2.3.3", "react-native-notifications": "^1.2.0", "react-native-photo-view": "alwx/react-native-photo-view#c58fd6b30", + "react-native-reanimated": "^1.0.0", "react-native-safari-view": "2.0.0", "react-native-safe-area": "^0.4.1", - "react-native-screens": "^1.0.0-alpha.23", + "react-native-safe-area-context": "^3.1.7", + "react-native-screens": "^2.10.1", "react-native-simple-toast": "^1.0.0", "react-native-sound": "^0.11.0", "react-native-text-input-reset": "^1.0.2", @@ -76,11 +78,11 @@ "react-native-url-polyfill": "1.2.0-rc.0", "react-native-vector-icons": "^6.6.0", "react-native-webview": "~10.0.0", - "react-navigation": "^3.13.0", - "react-navigation-drawer": "~1.4.0", + "react-navigation": "^4.4.0", + "react-navigation-drawer": "^2.5.0", "react-navigation-redux-helpers": "^3.0.8", - "react-navigation-stack": "1.5.3", - "react-navigation-tabs": "~1.2.0", + "react-navigation-stack": "^2.8.2", + "react-navigation-tabs": "^2.9.0", "react-redux": "^5.0.7", "redux": "^4.0.0", "redux-action-buffer": "^1.2.0", diff --git a/src/nav/AppNavigator.js b/src/nav/AppNavigator.js index 082a137688a..5a6ed9adfc3 100644 --- a/src/nav/AppNavigator.js +++ b/src/nav/AppNavigator.js @@ -1,5 +1,5 @@ /* @flow strict-local */ -import { createStackNavigator } from 'react-navigation'; +import { createStackNavigator } from 'react-navigation-stack'; import AccountPickScreen from '../account/AccountPickScreen'; import RealmScreen from '../start/RealmScreen'; diff --git a/yarn.lock b/yarn.lock index 1f97074db6e..6ca01205517 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1505,12 +1505,17 @@ wcwidth "^1.0.1" ws "^1.1.0" +"@react-native-community/masked-view@^0.1.10": + version "0.1.10" + resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.10.tgz#5dda643e19e587793bc2034dd9bf7398ad43d401" + integrity sha512-rk4sWFsmtOw8oyx8SD3KSvawwaK7gRBSEIy2TAwURyGt+3TizssXP1r8nx3zY+R7v2vYYHXZ+k2/GULAT/bcaQ== + "@react-native-community/netinfo@^5.9.5": version "5.9.5" resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-5.9.5.tgz#3bad0d855d2e813be085ec305139d4175c512ccc" integrity sha512-PbSsRmhRwYIMdeVJTf9gJtvW0TVq/hmgz1xyjsrTIsQ7QS7wbMEiv1Eb/M/y6AEEsdUped5Axm5xykq9TGISHg== -"@react-navigation/core@^3.5.0": +"@react-navigation/core@^3.7.6": version "3.7.6" resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.7.6.tgz#e0244fcdc22937825b252197f70308bbe5709c58" integrity sha512-loYFIn0Boy7C+vYxwcqsBVRFRO1EizZJErdutE6/3Jw6dbzz3Bnzupbw5hckZNB16GckacMwGoepZNIK51IIcg== @@ -1520,17 +1525,7 @@ query-string "^6.11.1" react-is "^16.13.0" -"@react-navigation/core@~3.5.1": - version "3.5.2" - resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.5.2.tgz#3a3d147b8419e5839e0f2ad4dea086bd2d307fe3" - integrity sha512-HgKXci1h74aETgm5CXMBoIWG8R7VZG1eUUHYb3BdxwekdiZjW1P/srjiXzsCqFGlsESnVIOIkzT4DqI9J752Bw== - dependencies: - hoist-non-react-statics "^3.3.0" - path-to-regexp "^1.7.0" - query-string "^6.4.2" - react-is "^16.8.6" - -"@react-navigation/native@^3.6.2": +"@react-navigation/native@^3.8.0": version "3.8.0" resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.8.0.tgz#35882c3fc2f997ea1a43c12a15088cf4c818fd92" integrity sha512-Uym5XdNOTpTR6XC4IVa/Shfn12DUF3DUIqch+cpiLNfvauQukVmWoz+Rfxd2faGOzxT12EhrWGFsMJ/8nuTfcw== @@ -1538,14 +1533,6 @@ hoist-non-react-statics "^3.3.2" react-native-safe-area-view "^0.14.9" -"@react-navigation/native@~3.6.2": - version "3.6.5" - resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.6.5.tgz#97b0b9a48f059a0704e3527f40fb034720ef363d" - integrity sha512-ttEmnokFVf09CvrkzlPIdfA693KfYcRxTYf9OZwp0Ll6El27UYjJD4arwGc+zvlohjTErCdba6CAKV702Wv28w== - dependencies: - hoist-non-react-statics "^3.3.2" - react-native-safe-area-view "^0.14.8" - "@rollup/plugin-babel@^5.2.0": version "5.2.0" resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.2.0.tgz#b87556d61ed108b4eaf9d18b5323965adf8d9bee" @@ -3057,7 +3044,7 @@ color-support@^1.1.3: resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== -color@^3.0.0: +color@^3.0.0, color@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/color/-/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" integrity sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg== @@ -3386,11 +3373,6 @@ dayjs@^1.8.15: resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.27.tgz#a8ae63ee990af28c05c430f0e160ae835a0fbbf8" integrity sha512-Jpa2acjWIeOkg8KURUHICk0EqnEFSSF5eMEscsOgyJ92ZukXwmpmRkPSUka7KHSfbj5eKH30ieosYip+ky9emQ== -debounce@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.0.tgz#44a540abc0ea9943018dc0eaa95cce87f65cd131" - integrity sha512-mYtLl1xfZLi1m4RtQYlZgJUNQjl4ZxVnHzIR8nLLgi4q1YT8o/WM+MK/f8yfcc9s5Ir5zRaPZyZU6xs1Syoocg== - debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -4937,7 +4919,7 @@ hermes-engine@^0.2.1: resolved "https://registry.yarnpkg.com/hermes-engine/-/hermes-engine-0.2.1.tgz#25c0f1ff852512a92cb5c5cc47cf967e1e722ea2" integrity sha512-eNHUQHuadDMJARpaqvlCZoK/Nitpj6oywq3vQ3wCwEsww5morX34mW5PmKWQTO7aU0ck0hgulxR+EVDlXygGxQ== -hoist-non-react-statics@^2.3.1, hoist-non-react-statics@^2.5.0: +hoist-non-react-statics@^2.3.1: version "2.5.5" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47" integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw== @@ -7802,7 +7784,7 @@ path-parse@^1.0.6: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== -path-to-regexp@^1.7.0, path-to-regexp@^1.8.0: +path-to-regexp@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== @@ -8137,7 +8119,7 @@ query-string@^5.0.1: object-assign "^4.1.0" strict-uri-encode "^1.0.0" -query-string@^6.11.1, query-string@^6.4.2: +query-string@^6.11.1: version "6.13.1" resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.13.1.tgz#d913ccfce3b4b3a713989fe6d39466d92e71ccad" integrity sha512-RfoButmcK+yCta1+FuU8REvisx1oEzhMKwhLUNcepQTPGcNMp1sIqjnfCtfnvGSQZQEhaBHvccujtWoUV3TTbA== @@ -8199,12 +8181,12 @@ react-intl@^2.4.0: intl-relativeformat "^2.1.0" invariant "^2.1.1" -react-is@^16.12.0, react-is@^16.13.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6: +react-is@^16.12.0, react-is@^16.13.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-lifecycles-compat@^3.0.0: +react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== @@ -8244,6 +8226,11 @@ react-native-image-picker@^2.3.3: resolved "https://registry.yarnpkg.com/react-native-image-picker/-/react-native-image-picker-2.3.3.tgz#eaacd4a1ed9e9887613be31f0765478ca2f18a51" integrity sha512-i/7JDnxKkUGSbFY2i7YqFNn3ncJm1YlcrPKXrXmJ/YUElz8tHkuwknuqBd9QCJivMfHX41cmq4XvdBDwIOtO+A== +react-native-iphone-x-helper@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.2.1.tgz#645e2ffbbb49e80844bb4cbbe34a126fda1e6772" + integrity sha512-/VbpIEp8tSNNHIvstuA3Swx610whci1Zpc9mqNkqn14DkMbw+ORviln2u0XyHG1kPvvwTNGZY6QpeFwxYaSdbQ== + react-native-notifications@^1.2.0: version "1.5.0" resolved "https://registry.yarnpkg.com/react-native-notifications/-/react-native-notifications-1.5.0.tgz#2517381f8611433910f16c0e8d94d7966e6f2490" @@ -8258,12 +8245,24 @@ react-native-photo-view@alwx/react-native-photo-view#c58fd6b30: dependencies: prop-types "^15.5.10" +react-native-reanimated@^1.0.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.13.0.tgz#1ee5d27d34bd2cee7dfad4ae9a3673300872c917" + integrity sha512-uadP/0QO+4TCsyPSvzRdl+76NPM7Bp8M25KQLB4Hg3tWBMjhrMrETnzNi33L/OPfmhU+7rceyi0QPe/DxKT5bQ== + dependencies: + fbjs "^1.0.0" + react-native-safari-view@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/react-native-safari-view/-/react-native-safari-view-2.0.0.tgz#3aeb40693b0765df16b9beaf8654b60c7ff1d7ed" integrity sha1-OutAaTsHZd8Wub6vhlS2DH/x1+0= -react-native-safe-area-view@^0.14.8, react-native-safe-area-view@^0.14.9: +react-native-safe-area-context@^3.1.7: + version "3.1.7" + resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-3.1.7.tgz#fc9e636dfb168f992a2172d363509ce0611a8403" + integrity sha512-qSyg/pVMwVPgAy8yCvw349Q+uEUhtRBV33eVXHHkfoou1vCChJxI7SmNR47/6M3BLdjWcyc4lcd018Kx+jhQCw== + +react-native-safe-area-view@^0.14.9: version "0.14.9" resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.9.tgz#90ee8383037010d9a5055a97cf97e4c1da1f0c3d" integrity sha512-WII/ulhpVyL/qbYb7vydq7dJAfZRBcEhg4/UWt6F6nAKpLa3gAceMOxBxI914ppwSP/TdUsandFy6lkJQE0z4A== @@ -8275,12 +8274,10 @@ react-native-safe-area@^0.4.1: resolved "https://registry.yarnpkg.com/react-native-safe-area/-/react-native-safe-area-0.4.4.tgz#c9e267ef06cd6047da854c30e6c955eff7cc7105" integrity sha512-u1RmFqJMmlzqDT5SezAfRv8MCLwteKsB1fPym4J//wy9zIuYJe60Ni664NRwqCKwDyQmwGcvfGqmA1hTpOOhhQ== -react-native-screens@^1.0.0-alpha.23: - version "1.0.0-alpha.23" - resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-1.0.0-alpha.23.tgz#25d7ea4d11bda4fcde2d1da7ae50271c6aa636e0" - integrity sha512-tOxHGQUN83MTmQB4ghoQkibqOdGiX4JQEmeyEv96MKWO/x8T2PJv84ECUos9hD3blPRQwVwSpAid1PPPhrVEaw== - dependencies: - debounce "^1.2.0" +react-native-screens@^2.10.1: + version "2.10.1" + resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-2.10.1.tgz#06d22fae87ef0ce51c616c34a199726db1403b95" + integrity sha512-Z2kKSk4AwWRQNCBmTjViuBQK0/Lx0jc25TZptn/2gKYUCOuVRvCekoA26u0Tsb3BIQ8tWDsZW14OwDlFUXW1aw== react-native-simple-toast@^1.0.0: version "1.0.0" @@ -8292,12 +8289,10 @@ react-native-sound@^0.11.0: resolved "https://registry.yarnpkg.com/react-native-sound/-/react-native-sound-0.11.0.tgz#ad60b55ba8c6dc89917f381ad3713f2738de530f" integrity sha512-4bGAZfni6E2L695NQjOZwNLBQGXgBGYC4Sy+h99K5h0HqNZjCqR0+aLel+ezASxEJDpaH83gylNObXpiqJgdwg== -react-native-tab-view@^1.2.0, react-native-tab-view@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-1.4.1.tgz#f113cd87485808f0c991abec937f70fa380478b9" - integrity sha512-Bke8KkDcDhvB/z0AS7MnQKMD2p6Kwfc1rSKlMOvg9CC5CnClQ2QEnhPSbwegKDYhUkBI92iH/BYy7hNSm5kbUQ== - dependencies: - prop-types "^15.6.1" +react-native-tab-view@^2.11.0: + version "2.15.1" + resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-2.15.1.tgz#cf4df4ffdec504263a2e06a6becd8831b9a19ad9" + integrity sha512-cDYl1pNWspbEHBjHrHVpIC40h4g8VhZe0CIG0CUKcouX98vHVfAojxhgWuRosq9qMhITHpLKM+7BmBLnhCJ0nw== react-native-text-input-reset@^1.0.2: version "1.0.2" @@ -8388,12 +8383,10 @@ react-native@0.61.5: stacktrace-parser "^0.1.3" whatwg-fetch "^3.0.0" -react-navigation-drawer@~1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/react-navigation-drawer/-/react-navigation-drawer-1.4.0.tgz#70f3dd83e3da9cd4ea6e2739526502c823d466b9" - integrity sha512-ZyWBozcjB2aZ7vwCALv90cYA2NpDjM+WALaiYRshvPvue8l7cqynePbHK8GhlMGyJDwZqp4MxQmu8u1XAKp3Bw== - dependencies: - react-native-tab-view "^1.2.0" +react-navigation-drawer@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/react-navigation-drawer/-/react-navigation-drawer-2.5.0.tgz#6d2940fb6f9ae557b47a717203b4058194ae9665" + integrity sha512-wSsIdLYXYdi9wOOXGzaY4Hk/NIXaP8tClEpjlAPl1rhn3kU++gyJFcQ3xLsPWg0yRYq3y8jDPEWFFf81JqfP9Q== react-navigation-redux-helpers@^3.0.8: version "3.0.8" @@ -8402,32 +8395,31 @@ react-navigation-redux-helpers@^3.0.8: dependencies: invariant "^2.2.2" -react-navigation-stack@1.5.3: - version "1.5.3" - resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-1.5.3.tgz#cdc9f5a6dbdc55509a15f60d765722573dec1997" - integrity sha512-MQcwDVbZUYsTtDJb5cFOSm+K+e7KpUCoROaGoUOR+JHWE3uuaJ3pd/Nu+32a57J98TNBf4qq0+2TPJWl6z6IBg== +react-navigation-stack@^2.8.2: + version "2.8.2" + resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.8.2.tgz#e982bbf14a28b23c323b2d4a6fce4e9754b066e6" + integrity sha512-e1VtlF6NDdzgKmnqE3ucgizrgUWUakdT+r7htQU24iG8AJUFQEw+tH4Lfyj0St6i8/RLckXm+o9VgYJT+pNiRw== dependencies: - prop-types "^15.7.2" + color "^3.1.2" + react-native-iphone-x-helper "^1.2.1" -react-navigation-tabs@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-1.2.0.tgz#602c147029bb4f1c569b26479ddba534fe3ebb19" - integrity sha512-I6vq3XX4ub9KhWQzcrggznls+2Z2C6w2ro46vokDGGvJ02CBpQRar7J0ETV29Ot5AJY67HucNUmZdH3yDFckmQ== +react-navigation-tabs@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-2.9.0.tgz#37407106f33367ff0ef3e5bb128d03f2721a50ef" + integrity sha512-+C9wyPtgxpEedhs1aX8pwtM7gJtpDMN3wPwq0jNkmONaurhb3hvE+mt3D7CLtX+zwxmMhcrPxSTSkynORKNn8g== dependencies: - hoist-non-react-statics "^2.5.0" - prop-types "^15.6.1" - react-native-tab-view "^1.4.1" - -react-navigation@^3.13.0: - version "3.13.0" - resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.13.0.tgz#e802bb5174c1ec8b727c69f8e4409ff1351a5250" - integrity sha512-r64bTImY2aNye8wtd39ubouVB6ZMJqjVQYKxH4LFmOav4FsI59fQTDN7sZzyJa29owowYw/wVkh+NWGT+tdD1A== - dependencies: - "@react-navigation/core" "~3.5.1" - "@react-navigation/native" "~3.6.2" - react-navigation-drawer "~1.4.0" - react-navigation-stack "1.5.3" - react-navigation-tabs "~1.2.0" + hoist-non-react-statics "^3.3.2" + react-lifecycles-compat "^3.0.4" + react-native-safe-area-view "^0.14.9" + react-native-tab-view "^2.11.0" + +react-navigation@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-4.4.0.tgz#c5523669df642aab23ff9e2ceb2109d3492a9374" + integrity sha512-BtxqNNlEGm/ve1mGHxCvrtvDzZ+2OF/V9OJaDPz/Cdx2VvYiFGaq6mtlFQm5/2bLxiEVXhNFcYSTCP26YGiENA== + dependencies: + "@react-navigation/core" "^3.7.6" + "@react-navigation/native" "^3.8.0" react-redux@^5.0.7: version "5.1.1" From 991b0368f123a79a640d7a124ac94df894a12ab1 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Mon, 14 Sep 2020 17:37:18 -0700 Subject: [PATCH 6/7] android nav: Use a better stack-nav animation. In one of the recent React Navigation upgrades, the animation for a new screen entering and leaving the stack, on Android, changed. We like how it was before [1]. So, put it back. [1] https://github.com/zulip/zulip-mobile/pull/4249#issuecomment-691388484 --- src/nav/AppNavigator.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/nav/AppNavigator.js b/src/nav/AppNavigator.js index 5a6ed9adfc3..5ea177fa1ed 100644 --- a/src/nav/AppNavigator.js +++ b/src/nav/AppNavigator.js @@ -1,5 +1,17 @@ /* @flow strict-local */ -import { createStackNavigator } from 'react-navigation-stack'; +import { Platform } from 'react-native'; +import { + createStackNavigator, + // The FlowTyped libdef skips v2; there's one for + // `react-navigation-stack` v1 (we're using that one), and there's + // one for `@react-navigation/stack` v5, which we'll use when we're + // on React Navigation v5. `TransitionPresets` is missing in the v1 + // libdef. We could go add it in ourselves, but our use of it is + // small and isolated, so we might as well wait for the + // `@react-navigation/stack` libdef. + // $FlowFixMe + TransitionPresets, +} from 'react-navigation-stack'; import AccountPickScreen from '../account/AccountPickScreen'; import RealmScreen from '../start/RealmScreen'; @@ -69,6 +81,12 @@ export default createStackNavigator( sharing: { screen: SharingScreen }, }, { + defaultNavigationOptions: { + ...Platform.select({ + android: TransitionPresets.FadeFromBottomAndroid, + ios: TransitionPresets.DefaultTransition, + }), + }, initialRouteName: 'main', headerMode: 'none', }, From ad0b5f3e0c39aac0512ec33e22956f8a5323fb46 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Mon, 14 Sep 2020 17:43:38 -0700 Subject: [PATCH 7/7] nav: Enable swiping between top tabs. In one of the recent React Navigation upgrades, a rapid sideways scroll animation was added for when you tap another tab to switch to it. This feels better than having no animation, but it really suggests that swiping ought to work to switch between tabs [1]. We haven't been offering that; so, do that. [1] https://github.com/zulip/zulip-mobile/pull/4249#issuecomment-691388484 Fixes: #3997 --- src/main/StreamTabs.js | 1 + src/reactions/MessageReactionList.js | 1 + src/sharing/SharingScreen.js | 1 + 3 files changed, 3 insertions(+) diff --git a/src/main/StreamTabs.js b/src/main/StreamTabs.js index f28708b986c..9f344cb6a5c 100644 --- a/src/main/StreamTabs.js +++ b/src/main/StreamTabs.js @@ -45,5 +45,6 @@ export default createMaterialTopTabNavigator( showLabel: true, showIcon: false, }), + swipeEnabled: true, }, ); diff --git a/src/reactions/MessageReactionList.js b/src/reactions/MessageReactionList.js index f425c36c189..05d72ebd989 100644 --- a/src/reactions/MessageReactionList.js +++ b/src/reactions/MessageReactionList.js @@ -95,6 +95,7 @@ const getReactionsTabs = ( borderWidth: 0.15, }, }), + swipeEnabled: true, }), ); }; diff --git a/src/sharing/SharingScreen.js b/src/sharing/SharingScreen.js index 6524a6f9786..d57745ebc77 100644 --- a/src/sharing/SharingScreen.js +++ b/src/sharing/SharingScreen.js @@ -55,6 +55,7 @@ const SharingTopTabNavigator = createMaterialTopTabNavigator( showLabel: true, showIcon: false, }), + swipeEnabled: true, }, );