diff --git a/native/chat/text-message-tooltip-modal.react.js b/native/chat/text-message-tooltip-modal.react.js index 9ffbf8566..66966394a 100644 --- a/native/chat/text-message-tooltip-modal.react.js +++ b/native/chat/text-message-tooltip-modal.react.js @@ -1,76 +1,76 @@ // @flow -import Clipboard from '@react-native-community/clipboard'; +import Clipboard from '@react-native-clipboard/clipboard'; import invariant from 'invariant'; import * as React from 'react'; import { createMessageReply } from 'lib/shared/message-utils'; import type { DispatchFunctions, BindServerCall } from 'lib/utils/action-utils'; import type { InputState } from '../input/input-state'; import { displayActionResultModal } from '../navigation/action-result-modal'; import { createTooltip, tooltipHeight, type TooltipParams, type TooltipRoute, type BaseTooltipProps, } from '../navigation/tooltip.react'; import type { ChatTextMessageInfoItemWithHeight } from '../types/chat-types'; import { onPressReport } from './message-report-utils'; import { navigateToSidebar } from './sidebar-navigation'; import TextMessageTooltipButton from './text-message-tooltip-button.react'; export type TextMessageTooltipModalParams = TooltipParams<{ +item: ChatTextMessageInfoItemWithHeight, }>; const confirmCopy = () => displayActionResultModal('copied!'); function onPressCopy(route: TooltipRoute<'TextMessageTooltipModal'>) { Clipboard.setString(route.params.item.messageInfo.text); setTimeout(confirmCopy); } function onPressReply( route: TooltipRoute<'TextMessageTooltipModal'>, dispatchFunctions: DispatchFunctions, bindServerCall: BindServerCall, inputState: ?InputState, ) { invariant( inputState, 'inputState should be set in TextMessageTooltipModal.onPressReply', ); inputState.addReply(createMessageReply(route.params.item.messageInfo.text)); } const spec = { entries: [ { id: 'copy', text: 'Copy', onPress: onPressCopy }, { id: 'reply', text: 'Reply', onPress: onPressReply }, { id: 'report', text: 'Report', onPress: onPressReport, }, { id: 'create_sidebar', text: 'Create thread', onPress: navigateToSidebar, }, { id: 'open_sidebar', text: 'Go to thread', onPress: navigateToSidebar, }, ], }; const TextMessageTooltipModal: React.ComponentType< BaseTooltipProps<'TextMessageTooltipModal'>, > = createTooltip<'TextMessageTooltipModal'>(TextMessageTooltipButton, spec); const textMessageTooltipHeight: number = tooltipHeight(spec.entries.length); export { TextMessageTooltipModal, textMessageTooltipHeight }; diff --git a/native/crash.react.js b/native/crash.react.js index 290b6e2e8..ed07bdac8 100644 --- a/native/crash.react.js +++ b/native/crash.react.js @@ -1,293 +1,293 @@ // @flow -import Clipboard from '@react-native-community/clipboard'; +import Clipboard from '@react-native-clipboard/clipboard'; import invariant from 'invariant'; import _shuffle from 'lodash/fp/shuffle'; import * as React from 'react'; import { View, Text, Platform, StyleSheet, ScrollView, ActivityIndicator, } from 'react-native'; import ExitApp from 'react-native-exit-app'; import Icon from 'react-native-vector-icons/FontAwesome'; import { sendReportActionTypes, sendReport } from 'lib/actions/report-actions'; import { logOutActionTypes, logOut } from 'lib/actions/user-actions'; import { preRequestUserStateSelector } from 'lib/selectors/account-selectors'; import type { LogOutResult } from 'lib/types/account-types'; import type { ErrorData } from 'lib/types/report-types'; import { type ClientReportCreationRequest, type ReportCreationResponse, reportTypes, } from 'lib/types/report-types'; import type { PreRequestUserState } from 'lib/types/session-types'; import { actionLogger } from 'lib/utils/action-logger'; import { type DispatchActionPromise, useServerCall, useDispatchActionPromise, } from 'lib/utils/action-utils'; import { useIsReportEnabled } from 'lib/utils/report-utils'; import { sanitizeReduxReport, type ReduxCrashReport, } from 'lib/utils/sanitization'; import sleep from 'lib/utils/sleep'; import Button from './components/button.react'; import ConnectedStatusBar from './connected-status-bar.react'; import { persistConfig, codeVersion } from './redux/persist'; import { useSelector } from './redux/redux-utils'; import { wipeAndExit } from './utils/crash-utils'; const errorTitles = ['Oh no!!', 'Womp womp womp...']; type BaseProps = { +errorData: $ReadOnlyArray, }; type Props = { ...BaseProps, // Redux state +preRequestUserState: PreRequestUserState, // Redux dispatch functions +dispatchActionPromise: DispatchActionPromise, // async functions that hit server APIs +sendReport: ( request: ClientReportCreationRequest, ) => Promise, +logOut: (preRequestUserState: PreRequestUserState) => Promise, +crashReportingEnabled: boolean, }; type State = { +errorReportID: ?string, +doneWaiting: boolean, }; class Crash extends React.PureComponent { errorTitle = _shuffle(errorTitles)[0]; constructor(props) { super(props); this.state = { errorReportID: null, doneWaiting: !props.crashReportingEnabled, }; } componentDidMount() { if (this.state.doneWaiting) { return; } this.props.dispatchActionPromise(sendReportActionTypes, this.sendReport()); this.timeOut(); } async timeOut() { // If it takes more than 10s, give up and let the user exit await sleep(10000); this.setState({ doneWaiting: true }); } render() { const errorText = [...this.props.errorData] .reverse() .map(errorData => errorData.error.message) .join('\n'); let crashID; if (!this.state.doneWaiting) { crashID = ; } else if (this.state.doneWaiting && this.state.errorReportID) { crashID = ( Crash report ID: {this.state.errorReportID} ); } else { crashID = ( Crash reporting can be enabled in the Profile tab. ); } const buttonStyle = { opacity: Number(this.state.doneWaiting) }; return ( {this.errorTitle} I'm sorry, but the app crashed. {crashID} Here's some text that's probably not helpful: {errorText} ); } async sendReport() { const sanitizedReduxReport: ReduxCrashReport = sanitizeReduxReport({ preloadedState: actionLogger.preloadedState, currentState: actionLogger.currentState, actions: actionLogger.actions, }); const result = await this.props.sendReport({ type: reportTypes.ERROR, platformDetails: { platform: Platform.OS, codeVersion, stateVersion: persistConfig.version, }, errors: this.props.errorData.map(data => ({ errorMessage: data.error.message, stack: data.error.stack, componentStack: data.info && data.info.componentStack, })), ...sanitizedReduxReport, }); this.setState({ errorReportID: result.id, doneWaiting: true, }); } onPressKill = () => { if (!this.state.doneWaiting) { return; } ExitApp.exitApp(); }; onPressWipe = async () => { if (!this.state.doneWaiting) { return; } this.props.dispatchActionPromise(logOutActionTypes, this.logOutAndExit()); }; async logOutAndExit() { try { await this.props.logOut(this.props.preRequestUserState); } catch (e) {} await wipeAndExit(); } onCopyCrashReportID = () => { invariant(this.state.errorReportID, 'should be set'); Clipboard.setString(this.state.errorReportID); }; } const styles = StyleSheet.create({ button: { backgroundColor: '#FF0000', borderRadius: 5, marginHorizontal: 10, paddingHorizontal: 10, paddingVertical: 5, }, buttonText: { color: 'white', fontSize: 16, }, buttons: { flexDirection: 'row', }, container: { alignItems: 'center', backgroundColor: 'white', flex: 1, justifyContent: 'center', }, copyCrashReportIDButtonText: { color: '#036AFF', }, crashID: { flexDirection: 'row', paddingBottom: 12, paddingTop: 2, }, crashIDText: { color: 'black', paddingRight: 8, }, errorReportID: { flexDirection: 'row', height: 20, }, errorReportIDText: { color: 'black', paddingRight: 8, }, errorText: { color: 'black', fontFamily: Platform.select({ ios: 'Menlo', default: 'monospace', }), }, header: { color: 'black', fontSize: 24, paddingBottom: 24, }, scrollView: { flex: 1, marginBottom: 24, marginTop: 12, maxHeight: 200, paddingHorizontal: 50, }, text: { color: 'black', paddingBottom: 12, }, }); const ConnectedCrash: React.ComponentType = React.memo( function ConnectedCrash(props: BaseProps) { const preRequestUserState = useSelector(preRequestUserStateSelector); const dispatchActionPromise = useDispatchActionPromise(); const callSendReport = useServerCall(sendReport); const callLogOut = useServerCall(logOut); const crashReportingEnabled = useIsReportEnabled('crashReports'); return ( ); }, ); export default ConnectedCrash; diff --git a/native/ios/Podfile.lock b/native/ios/Podfile.lock index b70ee2490..7231844c2 100644 --- a/native/ios/Podfile.lock +++ b/native/ios/Podfile.lock @@ -1,1324 +1,1324 @@ PODS: - abseil/algorithm/algorithm (1.20210324.0): - abseil/base/config - abseil/algorithm/container (1.20210324.0): - abseil/algorithm/algorithm - abseil/base/core_headers - abseil/meta/type_traits - abseil/base/atomic_hook (1.20210324.0): - abseil/base/config - abseil/base/core_headers - abseil/base/base (1.20210324.0): - abseil/base/atomic_hook - abseil/base/base_internal - abseil/base/config - abseil/base/core_headers - abseil/base/dynamic_annotations - abseil/base/log_severity - abseil/base/raw_logging_internal - abseil/base/spinlock_wait - abseil/meta/type_traits - abseil/base/base_internal (1.20210324.0): - abseil/base/config - abseil/meta/type_traits - abseil/base/config (1.20210324.0) - abseil/base/core_headers (1.20210324.0): - abseil/base/config - abseil/base/dynamic_annotations (1.20210324.0): - abseil/base/config - abseil/base/core_headers - abseil/base/endian (1.20210324.0): - abseil/base/base - abseil/base/config - abseil/base/core_headers - abseil/base/errno_saver (1.20210324.0): - abseil/base/config - abseil/base/exponential_biased (1.20210324.0): - abseil/base/config - abseil/base/core_headers - abseil/base/log_severity (1.20210324.0): - abseil/base/config - abseil/base/core_headers - abseil/base/malloc_internal (1.20210324.0): - abseil/base/base - abseil/base/base_internal - abseil/base/config - abseil/base/core_headers - abseil/base/dynamic_annotations - abseil/base/raw_logging_internal - abseil/base/raw_logging_internal (1.20210324.0): - abseil/base/atomic_hook - abseil/base/config - abseil/base/core_headers - abseil/base/log_severity - abseil/base/spinlock_wait (1.20210324.0): - abseil/base/base_internal - abseil/base/core_headers - abseil/base/errno_saver - abseil/base/throw_delegate (1.20210324.0): - abseil/base/config - abseil/base/raw_logging_internal - abseil/container/common (1.20210324.0): - abseil/meta/type_traits - abseil/types/optional - abseil/container/compressed_tuple (1.20210324.0): - abseil/utility/utility - abseil/container/container_memory (1.20210324.0): - abseil/base/config - abseil/memory/memory - abseil/meta/type_traits - abseil/utility/utility - abseil/container/fixed_array (1.20210324.0): - abseil/algorithm/algorithm - abseil/base/config - abseil/base/core_headers - abseil/base/dynamic_annotations - abseil/base/throw_delegate - abseil/container/compressed_tuple - abseil/memory/memory - abseil/container/flat_hash_map (1.20210324.0): - abseil/algorithm/container - abseil/container/container_memory - abseil/container/hash_function_defaults - abseil/container/raw_hash_map - abseil/memory/memory - abseil/container/hash_function_defaults (1.20210324.0): - abseil/base/config - abseil/hash/hash - abseil/strings/cord - abseil/strings/strings - abseil/container/hash_policy_traits (1.20210324.0): - abseil/meta/type_traits - abseil/container/hashtable_debug_hooks (1.20210324.0): - abseil/base/config - abseil/container/hashtablez_sampler (1.20210324.0): - abseil/base/base - abseil/base/core_headers - abseil/base/exponential_biased - abseil/container/have_sse - abseil/debugging/stacktrace - abseil/memory/memory - abseil/synchronization/synchronization - abseil/utility/utility - abseil/container/have_sse (1.20210324.0) - abseil/container/inlined_vector (1.20210324.0): - abseil/algorithm/algorithm - abseil/base/core_headers - abseil/base/throw_delegate - abseil/container/inlined_vector_internal - abseil/memory/memory - abseil/container/inlined_vector_internal (1.20210324.0): - abseil/base/core_headers - abseil/container/compressed_tuple - abseil/memory/memory - abseil/meta/type_traits - abseil/types/span - abseil/container/layout (1.20210324.0): - abseil/base/config - abseil/base/core_headers - abseil/meta/type_traits - abseil/strings/strings - abseil/types/span - abseil/utility/utility - abseil/container/raw_hash_map (1.20210324.0): - abseil/base/throw_delegate - abseil/container/container_memory - abseil/container/raw_hash_set - abseil/container/raw_hash_set (1.20210324.0): - abseil/base/config - abseil/base/core_headers - abseil/base/endian - abseil/container/common - abseil/container/compressed_tuple - abseil/container/container_memory - abseil/container/hash_policy_traits - abseil/container/hashtable_debug_hooks - abseil/container/hashtablez_sampler - abseil/container/have_sse - abseil/container/layout - abseil/memory/memory - abseil/meta/type_traits - abseil/numeric/bits - abseil/utility/utility - abseil/debugging/debugging_internal (1.20210324.0): - abseil/base/config - abseil/base/core_headers - abseil/base/dynamic_annotations - abseil/base/errno_saver - abseil/base/raw_logging_internal - abseil/debugging/demangle_internal (1.20210324.0): - abseil/base/base - abseil/base/config - abseil/base/core_headers - abseil/debugging/stacktrace (1.20210324.0): - abseil/base/config - abseil/base/core_headers - abseil/debugging/debugging_internal - abseil/debugging/symbolize (1.20210324.0): - abseil/base/base - abseil/base/config - abseil/base/core_headers - abseil/base/dynamic_annotations - abseil/base/malloc_internal - abseil/base/raw_logging_internal - abseil/debugging/debugging_internal - abseil/debugging/demangle_internal - abseil/strings/strings - abseil/functional/bind_front (1.20210324.0): - abseil/base/base_internal - abseil/container/compressed_tuple - abseil/meta/type_traits - abseil/utility/utility - abseil/functional/function_ref (1.20210324.0): - abseil/base/base_internal - abseil/meta/type_traits - abseil/hash/city (1.20210324.0): - abseil/base/config - abseil/base/core_headers - abseil/base/endian - abseil/hash/hash (1.20210324.0): - abseil/base/config - abseil/base/core_headers - abseil/base/endian - abseil/container/fixed_array - abseil/hash/city - abseil/hash/wyhash - abseil/meta/type_traits - abseil/numeric/int128 - abseil/strings/strings - abseil/types/optional - abseil/types/variant - abseil/utility/utility - abseil/hash/wyhash (1.20210324.0): - abseil/base/config - abseil/base/endian - abseil/numeric/int128 - abseil/memory/memory (1.20210324.0): - abseil/base/core_headers - abseil/meta/type_traits - abseil/meta/type_traits (1.20210324.0): - abseil/base/config - abseil/numeric/bits (1.20210324.0): - abseil/base/config - abseil/base/core_headers - abseil/numeric/int128 (1.20210324.0): - abseil/base/config - abseil/base/core_headers - abseil/numeric/bits - abseil/numeric/representation (1.20210324.0): - abseil/base/config - abseil/status/status (1.20210324.0): - abseil/base/atomic_hook - abseil/base/config - abseil/base/core_headers - abseil/base/raw_logging_internal - abseil/container/inlined_vector - abseil/debugging/stacktrace - abseil/debugging/symbolize - abseil/strings/cord - abseil/strings/str_format - abseil/strings/strings - abseil/types/optional - abseil/status/statusor (1.20210324.0): - abseil/base/core_headers - abseil/base/raw_logging_internal - abseil/meta/type_traits - abseil/status/status - abseil/strings/strings - abseil/types/variant - abseil/utility/utility - abseil/strings/cord (1.20210324.0): - abseil/base/base - abseil/base/core_headers - abseil/base/endian - abseil/base/raw_logging_internal - abseil/container/fixed_array - abseil/container/inlined_vector - abseil/functional/function_ref - abseil/meta/type_traits - abseil/strings/cord_internal - abseil/strings/internal - abseil/strings/str_format - abseil/strings/strings - abseil/types/optional - abseil/strings/cord_internal (1.20210324.0): - abseil/base/base_internal - abseil/base/config - abseil/base/core_headers - abseil/base/endian - abseil/base/raw_logging_internal - abseil/base/throw_delegate - abseil/container/compressed_tuple - abseil/container/inlined_vector - abseil/container/layout - abseil/meta/type_traits - abseil/strings/strings - abseil/strings/internal (1.20210324.0): - abseil/base/config - abseil/base/core_headers - abseil/base/endian - abseil/base/raw_logging_internal - abseil/meta/type_traits - abseil/strings/str_format (1.20210324.0): - abseil/strings/str_format_internal - abseil/strings/str_format_internal (1.20210324.0): - abseil/base/config - abseil/base/core_headers - abseil/functional/function_ref - abseil/meta/type_traits - abseil/numeric/bits - abseil/numeric/int128 - abseil/numeric/representation - abseil/strings/strings - abseil/types/optional - abseil/types/span - abseil/strings/strings (1.20210324.0): - abseil/base/base - abseil/base/config - abseil/base/core_headers - abseil/base/endian - abseil/base/raw_logging_internal - abseil/base/throw_delegate - abseil/memory/memory - abseil/meta/type_traits - abseil/numeric/bits - abseil/numeric/int128 - abseil/strings/internal - abseil/synchronization/graphcycles_internal (1.20210324.0): - abseil/base/base - abseil/base/base_internal - abseil/base/config - abseil/base/core_headers - abseil/base/malloc_internal - abseil/base/raw_logging_internal - abseil/synchronization/kernel_timeout_internal (1.20210324.0): - abseil/base/core_headers - abseil/base/raw_logging_internal - abseil/time/time - abseil/synchronization/synchronization (1.20210324.0): - abseil/base/atomic_hook - abseil/base/base - abseil/base/base_internal - abseil/base/config - abseil/base/core_headers - abseil/base/dynamic_annotations - abseil/base/malloc_internal - abseil/base/raw_logging_internal - abseil/debugging/stacktrace - abseil/debugging/symbolize - abseil/synchronization/graphcycles_internal - abseil/synchronization/kernel_timeout_internal - abseil/time/time - abseil/time/internal/cctz/civil_time (1.20210324.0): - abseil/base/config - abseil/time/internal/cctz/time_zone (1.20210324.0): - abseil/base/config - abseil/time/internal/cctz/civil_time - abseil/time/time (1.20210324.0): - abseil/base/base - abseil/base/core_headers - abseil/base/raw_logging_internal - abseil/numeric/int128 - abseil/strings/strings - abseil/time/internal/cctz/civil_time - abseil/time/internal/cctz/time_zone - abseil/types/bad_optional_access (1.20210324.0): - abseil/base/config - abseil/base/raw_logging_internal - abseil/types/bad_variant_access (1.20210324.0): - abseil/base/config - abseil/base/raw_logging_internal - abseil/types/optional (1.20210324.0): - abseil/base/base_internal - abseil/base/config - abseil/base/core_headers - abseil/memory/memory - abseil/meta/type_traits - abseil/types/bad_optional_access - abseil/utility/utility - abseil/types/span (1.20210324.0): - abseil/algorithm/algorithm - abseil/base/core_headers - abseil/base/throw_delegate - abseil/meta/type_traits - abseil/types/variant (1.20210324.0): - abseil/base/base_internal - abseil/base/config - abseil/base/core_headers - abseil/meta/type_traits - abseil/types/bad_variant_access - abseil/utility/utility - abseil/utility/utility (1.20210324.0): - abseil/base/base_internal - abseil/base/config - abseil/meta/type_traits - boost (1.76.0) - CocoaAsyncSocket (7.6.5) - DoubleConversion (1.1.6) - DVAssetLoaderDelegate (0.3.3) - EXApplication (4.0.2): - ExpoModulesCore - EXConstants (12.1.3): - ExpoModulesCore - EXFileSystem (13.0.3): - ExpoModulesCore - EXFont (10.0.5): - ExpoModulesCore - EXHaptics (11.0.3): - ExpoModulesCore - EXImageLoader (3.0.0): - ExpoModulesCore - React-Core - EXImageManipulator (10.1.2): - EXImageLoader - ExpoModulesCore - EXKeepAwake (10.0.2): - ExpoModulesCore - EXMediaLibrary (13.0.3): - ExpoModulesCore - React-Core - Expo (43.0.0): - ExpoModulesCore - ExpoModulesCore (0.4.10): - React-Core - EXSecureStore (11.0.3): - ExpoModulesCore - EXSplashScreen (0.13.5): - ExpoModulesCore - React-Core - FBLazyVector (0.66.5) - FBReactNativeSpec (0.66.5): - RCT-Folly (= 2021.06.28.00-v2) - RCTRequired (= 0.66.5) - RCTTypeSafety (= 0.66.5) - React-Core (= 0.66.5) - React-jsi (= 0.66.5) - ReactCommon/turbomodule/core (= 0.66.5) - Flipper (0.99.0): - Flipper-Folly (~> 2.6) - Flipper-RSocket (~> 1.4) - Flipper-Boost-iOSX (1.76.0.1.11) - Flipper-DoubleConversion (1.1.7) - Flipper-Fmt (7.1.7) - Flipper-Folly (2.6.7): - Flipper-Boost-iOSX - Flipper-DoubleConversion - Flipper-Fmt (= 7.1.7) - Flipper-Glog - libevent (~> 2.1.12) - OpenSSL-Universal (= 1.1.180) - Flipper-Glog (0.3.6) - Flipper-PeerTalk (0.0.4) - Flipper-RSocket (1.4.3): - Flipper-Folly (~> 2.6) - FlipperKit (0.99.0): - FlipperKit/Core (= 0.99.0) - FlipperKit/Core (0.99.0): - Flipper (~> 0.99.0) - FlipperKit/CppBridge - FlipperKit/FBCxxFollyDynamicConvert - FlipperKit/FBDefines - FlipperKit/FKPortForwarding - FlipperKit/CppBridge (0.99.0): - Flipper (~> 0.99.0) - FlipperKit/FBCxxFollyDynamicConvert (0.99.0): - Flipper-Folly (~> 2.6) - FlipperKit/FBDefines (0.99.0) - FlipperKit/FKPortForwarding (0.99.0): - CocoaAsyncSocket (~> 7.6) - Flipper-PeerTalk (~> 0.0.4) - FlipperKit/FlipperKitHighlightOverlay (0.99.0) - FlipperKit/FlipperKitLayoutHelpers (0.99.0): - FlipperKit/Core - FlipperKit/FlipperKitHighlightOverlay - FlipperKit/FlipperKitLayoutTextSearchable - FlipperKit/FlipperKitLayoutIOSDescriptors (0.99.0): - FlipperKit/Core - FlipperKit/FlipperKitHighlightOverlay - FlipperKit/FlipperKitLayoutHelpers - YogaKit (~> 1.18) - FlipperKit/FlipperKitLayoutPlugin (0.99.0): - FlipperKit/Core - FlipperKit/FlipperKitHighlightOverlay - FlipperKit/FlipperKitLayoutHelpers - FlipperKit/FlipperKitLayoutIOSDescriptors - FlipperKit/FlipperKitLayoutTextSearchable - YogaKit (~> 1.18) - FlipperKit/FlipperKitLayoutTextSearchable (0.99.0) - FlipperKit/FlipperKitNetworkPlugin (0.99.0): - FlipperKit/Core - FlipperKit/FlipperKitReactPlugin (0.99.0): - FlipperKit/Core - FlipperKit/FlipperKitUserDefaultsPlugin (0.99.0): - FlipperKit/Core - FlipperKit/SKIOSNetworkPlugin (0.99.0): - FlipperKit/Core - FlipperKit/FlipperKitNetworkPlugin - fmt (6.2.1) - glog (0.3.5) - "gRPC-C++ (1.40.0)": - "gRPC-C++/Implementation (= 1.40.0)" - "gRPC-C++/Interface (= 1.40.0)" - "gRPC-C++/Implementation (1.40.0)": - abseil/base/base (= 1.20210324.0) - abseil/base/core_headers (= 1.20210324.0) - abseil/container/flat_hash_map (= 1.20210324.0) - abseil/container/inlined_vector (= 1.20210324.0) - abseil/functional/bind_front (= 1.20210324.0) - abseil/memory/memory (= 1.20210324.0) - abseil/status/status (= 1.20210324.0) - abseil/status/statusor (= 1.20210324.0) - abseil/strings/cord (= 1.20210324.0) - abseil/strings/str_format (= 1.20210324.0) - abseil/strings/strings (= 1.20210324.0) - abseil/synchronization/synchronization (= 1.20210324.0) - abseil/time/time (= 1.20210324.0) - abseil/types/optional (= 1.20210324.0) - "gRPC-C++/Interface (= 1.40.0)" - gRPC-Core (= 1.40.0) - "gRPC-C++/Interface (1.40.0)" - "gRPC-C++/Protobuf (1.40.0)": - "gRPC-C++/Interface (= 1.40.0)" - gRPC-Core (1.40.0): - gRPC-Core/Implementation (= 1.40.0) - gRPC-Core/Interface (= 1.40.0) - gRPC-Core/Implementation (1.40.0): - abseil/base/base (= 1.20210324.0) - abseil/base/core_headers (= 1.20210324.0) - abseil/container/flat_hash_map (= 1.20210324.0) - abseil/container/inlined_vector (= 1.20210324.0) - abseil/functional/bind_front (= 1.20210324.0) - abseil/memory/memory (= 1.20210324.0) - abseil/status/status (= 1.20210324.0) - abseil/status/statusor (= 1.20210324.0) - abseil/strings/cord (= 1.20210324.0) - abseil/strings/str_format (= 1.20210324.0) - abseil/strings/strings (= 1.20210324.0) - abseil/synchronization/synchronization (= 1.20210324.0) - abseil/time/time (= 1.20210324.0) - abseil/types/optional (= 1.20210324.0) - gRPC-Core/Interface (= 1.40.0) - OpenSSL-Universal - gRPC-Core/Interface (1.40.0) - hermes-engine (0.9.0) - libevent (2.1.12) - libwebp (1.2.1): - libwebp/demux (= 1.2.1) - libwebp/mux (= 1.2.1) - libwebp/webp (= 1.2.1) - libwebp/demux (1.2.1): - libwebp/webp - libwebp/mux (1.2.1): - libwebp/demux - libwebp/webp (1.2.1) - lottie-ios (3.1.8) - lottie-react-native (4.0.2): - lottie-ios (~> 3.1.8) - React-Core - mobile-ffmpeg-min (4.3.1.LTS) - OLMKit (3.2.4): - OLMKit/olmc (= 3.2.4) - OLMKit/olmcpp (= 3.2.4) - OLMKit/olmc (3.2.4) - OLMKit/olmcpp (3.2.4) - OpenSSL-Universal (1.1.180) - "Protobuf-C++ (3.15.8)" - RCT-Folly (2021.06.28.00-v2): - boost - DoubleConversion - fmt (~> 6.2.1) - glog - RCT-Folly/Default (= 2021.06.28.00-v2) - RCT-Folly/Default (2021.06.28.00-v2): - boost - DoubleConversion - fmt (~> 6.2.1) - glog - RCT-Folly/Futures (2021.06.28.00-v2): - boost - DoubleConversion - fmt (~> 6.2.1) - glog - libevent - RCTRequired (0.66.5) - RCTTypeSafety (0.66.5): - FBLazyVector (= 0.66.5) - RCT-Folly (= 2021.06.28.00-v2) - RCTRequired (= 0.66.5) - React-Core (= 0.66.5) - React (0.66.5): - React-Core (= 0.66.5) - React-Core/DevSupport (= 0.66.5) - React-Core/RCTWebSocket (= 0.66.5) - React-RCTActionSheet (= 0.66.5) - React-RCTAnimation (= 0.66.5) - React-RCTBlob (= 0.66.5) - React-RCTImage (= 0.66.5) - React-RCTLinking (= 0.66.5) - React-RCTNetwork (= 0.66.5) - React-RCTSettings (= 0.66.5) - React-RCTText (= 0.66.5) - React-RCTVibration (= 0.66.5) - React-callinvoker (0.66.5) - React-Core (0.66.5): - glog - RCT-Folly (= 2021.06.28.00-v2) - React-Core/Default (= 0.66.5) - React-cxxreact (= 0.66.5) - React-jsi (= 0.66.5) - React-jsiexecutor (= 0.66.5) - React-perflogger (= 0.66.5) - Yoga - React-Core/CoreModulesHeaders (0.66.5): - glog - RCT-Folly (= 2021.06.28.00-v2) - React-Core/Default - React-cxxreact (= 0.66.5) - React-jsi (= 0.66.5) - React-jsiexecutor (= 0.66.5) - React-perflogger (= 0.66.5) - Yoga - React-Core/Default (0.66.5): - glog - RCT-Folly (= 2021.06.28.00-v2) - React-cxxreact (= 0.66.5) - React-jsi (= 0.66.5) - React-jsiexecutor (= 0.66.5) - React-perflogger (= 0.66.5) - Yoga - React-Core/DevSupport (0.66.5): - glog - RCT-Folly (= 2021.06.28.00-v2) - React-Core/Default (= 0.66.5) - React-Core/RCTWebSocket (= 0.66.5) - React-cxxreact (= 0.66.5) - React-jsi (= 0.66.5) - React-jsiexecutor (= 0.66.5) - React-jsinspector (= 0.66.5) - React-perflogger (= 0.66.5) - Yoga - React-Core/RCTActionSheetHeaders (0.66.5): - glog - RCT-Folly (= 2021.06.28.00-v2) - React-Core/Default - React-cxxreact (= 0.66.5) - React-jsi (= 0.66.5) - React-jsiexecutor (= 0.66.5) - React-perflogger (= 0.66.5) - Yoga - React-Core/RCTAnimationHeaders (0.66.5): - glog - RCT-Folly (= 2021.06.28.00-v2) - React-Core/Default - React-cxxreact (= 0.66.5) - React-jsi (= 0.66.5) - React-jsiexecutor (= 0.66.5) - React-perflogger (= 0.66.5) - Yoga - React-Core/RCTBlobHeaders (0.66.5): - glog - RCT-Folly (= 2021.06.28.00-v2) - React-Core/Default - React-cxxreact (= 0.66.5) - React-jsi (= 0.66.5) - React-jsiexecutor (= 0.66.5) - React-perflogger (= 0.66.5) - Yoga - React-Core/RCTImageHeaders (0.66.5): - glog - RCT-Folly (= 2021.06.28.00-v2) - React-Core/Default - React-cxxreact (= 0.66.5) - React-jsi (= 0.66.5) - React-jsiexecutor (= 0.66.5) - React-perflogger (= 0.66.5) - Yoga - React-Core/RCTLinkingHeaders (0.66.5): - glog - RCT-Folly (= 2021.06.28.00-v2) - React-Core/Default - React-cxxreact (= 0.66.5) - React-jsi (= 0.66.5) - React-jsiexecutor (= 0.66.5) - React-perflogger (= 0.66.5) - Yoga - React-Core/RCTNetworkHeaders (0.66.5): - glog - RCT-Folly (= 2021.06.28.00-v2) - React-Core/Default - React-cxxreact (= 0.66.5) - React-jsi (= 0.66.5) - React-jsiexecutor (= 0.66.5) - React-perflogger (= 0.66.5) - Yoga - React-Core/RCTSettingsHeaders (0.66.5): - glog - RCT-Folly (= 2021.06.28.00-v2) - React-Core/Default - React-cxxreact (= 0.66.5) - React-jsi (= 0.66.5) - React-jsiexecutor (= 0.66.5) - React-perflogger (= 0.66.5) - Yoga - React-Core/RCTTextHeaders (0.66.5): - glog - RCT-Folly (= 2021.06.28.00-v2) - React-Core/Default - React-cxxreact (= 0.66.5) - React-jsi (= 0.66.5) - React-jsiexecutor (= 0.66.5) - React-perflogger (= 0.66.5) - Yoga - React-Core/RCTVibrationHeaders (0.66.5): - glog - RCT-Folly (= 2021.06.28.00-v2) - React-Core/Default - React-cxxreact (= 0.66.5) - React-jsi (= 0.66.5) - React-jsiexecutor (= 0.66.5) - React-perflogger (= 0.66.5) - Yoga - React-Core/RCTWebSocket (0.66.5): - glog - RCT-Folly (= 2021.06.28.00-v2) - React-Core/Default (= 0.66.5) - React-cxxreact (= 0.66.5) - React-jsi (= 0.66.5) - React-jsiexecutor (= 0.66.5) - React-perflogger (= 0.66.5) - Yoga - React-CoreModules (0.66.5): - FBReactNativeSpec (= 0.66.5) - RCT-Folly (= 2021.06.28.00-v2) - RCTTypeSafety (= 0.66.5) - React-Core/CoreModulesHeaders (= 0.66.5) - React-jsi (= 0.66.5) - React-RCTImage (= 0.66.5) - ReactCommon/turbomodule/core (= 0.66.5) - React-cxxreact (0.66.5): - boost (= 1.76.0) - DoubleConversion - glog - RCT-Folly (= 2021.06.28.00-v2) - React-callinvoker (= 0.66.5) - React-jsi (= 0.66.5) - React-jsinspector (= 0.66.5) - React-logger (= 0.66.5) - React-perflogger (= 0.66.5) - React-runtimeexecutor (= 0.66.5) - React-hermes (0.66.5): - DoubleConversion - glog - hermes-engine - RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly/Futures (= 2021.06.28.00-v2) - React-cxxreact (= 0.66.5) - React-jsi (= 0.66.5) - React-jsiexecutor (= 0.66.5) - React-jsinspector (= 0.66.5) - React-perflogger (= 0.66.5) - React-jsi (0.66.5): - boost (= 1.76.0) - DoubleConversion - glog - RCT-Folly (= 2021.06.28.00-v2) - React-jsi/Default (= 0.66.5) - React-jsi/Default (0.66.5): - boost (= 1.76.0) - DoubleConversion - glog - RCT-Folly (= 2021.06.28.00-v2) - React-jsiexecutor (0.66.5): - DoubleConversion - glog - RCT-Folly (= 2021.06.28.00-v2) - React-cxxreact (= 0.66.5) - React-jsi (= 0.66.5) - React-perflogger (= 0.66.5) - React-jsinspector (0.66.5) - React-logger (0.66.5): - glog - react-native-background-upload (6.5.1): - React - react-native-camera (3.31.0): - React - react-native-camera/RCT (= 3.31.0) - react-native-camera/RN (= 3.31.0) - react-native-camera/RCT (3.31.0): - React - react-native-camera/RN (3.31.0): - React - react-native-ffmpeg/min-lts (0.4.4): - mobile-ffmpeg-min (= 4.3.1.LTS) - React - react-native-flipper (0.98.0): - React-Core - react-native-in-app-message (1.0.2): - React - react-native-netinfo (6.0.0): - React-Core - react-native-notifications (1.1.19): - React - react-native-orientation-locker (1.1.6): - React - react-native-pager-view (6.0.1): - React-Core - react-native-safe-area-context (3.1.9): - React-Core - react-native-video/Video (5.1.1): - React-Core - react-native-video/VideoCaching (5.1.1): - DVAssetLoaderDelegate (~> 0.3.1) - React-Core - react-native-video/Video - SPTPersistentCache (~> 1.1.0) - react-native-webview (11.23.0): - React-Core - React-perflogger (0.66.5) - React-RCTActionSheet (0.66.5): - React-Core/RCTActionSheetHeaders (= 0.66.5) - React-RCTAnimation (0.66.5): - FBReactNativeSpec (= 0.66.5) - RCT-Folly (= 2021.06.28.00-v2) - RCTTypeSafety (= 0.66.5) - React-Core/RCTAnimationHeaders (= 0.66.5) - React-jsi (= 0.66.5) - ReactCommon/turbomodule/core (= 0.66.5) - React-RCTBlob (0.66.5): - FBReactNativeSpec (= 0.66.5) - RCT-Folly (= 2021.06.28.00-v2) - React-Core/RCTBlobHeaders (= 0.66.5) - React-Core/RCTWebSocket (= 0.66.5) - React-jsi (= 0.66.5) - React-RCTNetwork (= 0.66.5) - ReactCommon/turbomodule/core (= 0.66.5) - React-RCTImage (0.66.5): - FBReactNativeSpec (= 0.66.5) - RCT-Folly (= 2021.06.28.00-v2) - RCTTypeSafety (= 0.66.5) - React-Core/RCTImageHeaders (= 0.66.5) - React-jsi (= 0.66.5) - React-RCTNetwork (= 0.66.5) - ReactCommon/turbomodule/core (= 0.66.5) - React-RCTLinking (0.66.5): - FBReactNativeSpec (= 0.66.5) - React-Core/RCTLinkingHeaders (= 0.66.5) - React-jsi (= 0.66.5) - ReactCommon/turbomodule/core (= 0.66.5) - React-RCTNetwork (0.66.5): - FBReactNativeSpec (= 0.66.5) - RCT-Folly (= 2021.06.28.00-v2) - RCTTypeSafety (= 0.66.5) - React-Core/RCTNetworkHeaders (= 0.66.5) - React-jsi (= 0.66.5) - ReactCommon/turbomodule/core (= 0.66.5) - React-RCTSettings (0.66.5): - FBReactNativeSpec (= 0.66.5) - RCT-Folly (= 2021.06.28.00-v2) - RCTTypeSafety (= 0.66.5) - React-Core/RCTSettingsHeaders (= 0.66.5) - React-jsi (= 0.66.5) - ReactCommon/turbomodule/core (= 0.66.5) - React-RCTText (0.66.5): - React-Core/RCTTextHeaders (= 0.66.5) - React-RCTVibration (0.66.5): - FBReactNativeSpec (= 0.66.5) - RCT-Folly (= 2021.06.28.00-v2) - React-Core/RCTVibrationHeaders (= 0.66.5) - React-jsi (= 0.66.5) - ReactCommon/turbomodule/core (= 0.66.5) - React-runtimeexecutor (0.66.5): - React-jsi (= 0.66.5) - ReactCommon/turbomodule/core (0.66.5): - DoubleConversion - glog - RCT-Folly (= 2021.06.28.00-v2) - React-callinvoker (= 0.66.5) - React-Core (= 0.66.5) - React-cxxreact (= 0.66.5) - React-jsi (= 0.66.5) - React-logger (= 0.66.5) - React-perflogger (= 0.66.5) - ReactNativeART (1.2.0): - React - ReactNativeDarkMode (0.2.0-rc.1): - React - ReactNativeKeyboardInput (6.0.1): - React - ReactNativeKeyboardTrackingView (5.7.0): - React - RNCAsyncStorage (1.17.10): - React-Core - - RNCClipboard (1.5.1): + - RNCClipboard (1.11.1): - React-Core - SDWebImage (~> 5.8) - RNCMaskedView (0.2.8): - React-Core - RNDeviceInfo (8.0.7): - React-Core - RNExitApp (1.1.0): - React - RNFastImage (8.3.0): - React - SDWebImage (~> 5.8) - SDWebImageWebPCoder (~> 0.6.1) - RNFS (2.15.2): - React - RNGestureHandler (1.10.3): - React-Core - RNKeychain (8.0.0): - React-Core - RNReanimated (2.10.0): - DoubleConversion - FBLazyVector - FBReactNativeSpec - glog - RCT-Folly - RCTRequired - RCTTypeSafety - React-callinvoker - React-Core - React-Core/DevSupport - React-Core/RCTWebSocket - React-CoreModules - React-cxxreact - React-jsi - React-jsiexecutor - React-jsinspector - React-RCTActionSheet - React-RCTAnimation - React-RCTBlob - React-RCTImage - React-RCTLinking - React-RCTNetwork - React-RCTSettings - React-RCTText - ReactCommon/turbomodule/core - Yoga - RNScreens (3.8.0): - React-Core - React-RCTImage - RNSVG (12.3.0): - React-Core - RNVectorIcons (6.6.0): - React - SDWebImage (5.12.5): - SDWebImage/Core (= 5.12.5) - SDWebImage/Core (5.12.5) - SDWebImageWebPCoder (0.6.1): - libwebp (~> 1.0) - SDWebImage/Core (~> 5.7) - SPTPersistentCache (1.1.0) - SQLCipher-Amalgamation (4.4.3): - OpenSSL-Universal - SQLCipher-Amalgamation/standard (= 4.4.3) - SQLCipher-Amalgamation/common (4.4.3): - OpenSSL-Universal - SQLCipher-Amalgamation/standard (4.4.3): - OpenSSL-Universal - SQLCipher-Amalgamation/common - Yoga (1.14.0) - YogaKit (1.18.1): - Yoga (~> 1.14) DEPENDENCIES: - boost (from `../../node_modules/react-native/third-party-podspecs/boost.podspec`) - DoubleConversion (from `../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - EXApplication (from `../../node_modules/expo-application/ios`) - EXConstants (from `../../node_modules/expo-constants/ios`) - EXFileSystem (from `../../node_modules/expo-file-system/ios`) - EXFont (from `../../node_modules/expo-font/ios`) - EXHaptics (from `../../node_modules/expo-haptics/ios`) - EXImageLoader (from `../../node_modules/expo-image-loader/ios`) - EXImageManipulator (from `../../node_modules/expo-image-manipulator/ios`) - EXKeepAwake (from `../../node_modules/expo-keep-awake/ios`) - EXMediaLibrary (from `../../node_modules/expo-media-library/ios`) - Expo (from `../../node_modules/expo/ios`) - ExpoModulesCore (from `../../node_modules/expo-modules-core/ios`) - EXSecureStore (from `../../node_modules/expo-secure-store/ios`) - EXSplashScreen (from `../../node_modules/expo-splash-screen/ios`) - FBLazyVector (from `../../node_modules/react-native/Libraries/FBLazyVector`) - FBReactNativeSpec (from `../../node_modules/react-native/React/FBReactNativeSpec`) - Flipper (= 0.99.0) - Flipper-Boost-iOSX (= 1.76.0.1.11) - Flipper-DoubleConversion (= 1.1.7) - Flipper-Fmt (= 7.1.7) - Flipper-Folly (= 2.6.7) - Flipper-Glog (= 0.3.6) - Flipper-PeerTalk (= 0.0.4) - Flipper-RSocket (= 1.4.3) - FlipperKit (= 0.99.0) - FlipperKit/Core (= 0.99.0) - FlipperKit/CppBridge (= 0.99.0) - FlipperKit/FBCxxFollyDynamicConvert (= 0.99.0) - FlipperKit/FBDefines (= 0.99.0) - FlipperKit/FKPortForwarding (= 0.99.0) - FlipperKit/FlipperKitHighlightOverlay (= 0.99.0) - FlipperKit/FlipperKitLayoutPlugin (= 0.99.0) - FlipperKit/FlipperKitLayoutTextSearchable (= 0.99.0) - FlipperKit/FlipperKitNetworkPlugin (= 0.99.0) - FlipperKit/FlipperKitReactPlugin (= 0.99.0) - FlipperKit/FlipperKitUserDefaultsPlugin (= 0.99.0) - FlipperKit/SKIOSNetworkPlugin (= 0.99.0) - glog (from `../../node_modules/react-native/third-party-podspecs/glog.podspec`) - "gRPC-C++ (from `./pod-patch/.patched/gRPC-C++/1.40.0/gRPC-C++.podspec.json`)" - "gRPC-C++/Protobuf (from `./pod-patch/.patched/gRPC-C++/1.40.0/gRPC-C++.podspec.json`)" - gRPC-Core (from `./pod-patch/.patched/gRPC-Core/1.40.0/gRPC-Core.podspec.json`) - hermes-engine (~> 0.9.0) - libevent (~> 2.1.12) - lottie-ios (from `../../node_modules/lottie-ios`) - lottie-react-native (from `../../node_modules/lottie-react-native`) - OLMKit (from `../../node_modules/olm`) - "Protobuf-C++ (= 3.15.8)" - RCT-Folly (from `../../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) - RCTRequired (from `../../node_modules/react-native/Libraries/RCTRequired`) - RCTTypeSafety (from `../../node_modules/react-native/Libraries/TypeSafety`) - React (from `../../node_modules/react-native/`) - React-callinvoker (from `../../node_modules/react-native/ReactCommon/callinvoker`) - React-Core (from `../../node_modules/react-native/`) - React-Core/DevSupport (from `../../node_modules/react-native/`) - React-Core/RCTWebSocket (from `../../node_modules/react-native/`) - React-CoreModules (from `../../node_modules/react-native/React/CoreModules`) - React-cxxreact (from `../../node_modules/react-native/ReactCommon/cxxreact`) - React-hermes (from `../../node_modules/react-native/ReactCommon/hermes`) - React-jsi (from `../../node_modules/react-native/ReactCommon/jsi`) - React-jsiexecutor (from `../../node_modules/react-native/ReactCommon/jsiexecutor`) - React-jsinspector (from `../../node_modules/react-native/ReactCommon/jsinspector`) - React-logger (from `../../node_modules/react-native/ReactCommon/logger`) - react-native-background-upload (from `../../node_modules/react-native-background-upload`) - react-native-camera (from `../../node_modules/react-native-camera`) - react-native-ffmpeg/min-lts (from `../../node_modules/react-native-ffmpeg/react-native-ffmpeg.podspec`) - react-native-flipper (from `../../node_modules/react-native-flipper`) - react-native-in-app-message (from `../../node_modules/react-native-in-app-message`) - "react-native-netinfo (from `../../node_modules/@react-native-community/netinfo`)" - react-native-notifications (from `../../node_modules/react-native-notifications`) - react-native-orientation-locker (from `../../node_modules/react-native-orientation-locker`) - react-native-pager-view (from `../../node_modules/react-native-pager-view`) - react-native-safe-area-context (from `../../node_modules/react-native-safe-area-context`) - react-native-video/VideoCaching (from `../../node_modules/react-native-video/react-native-video.podspec`) - react-native-webview (from `../../node_modules/react-native-webview`) - React-perflogger (from `../../node_modules/react-native/ReactCommon/reactperflogger`) - React-RCTActionSheet (from `../../node_modules/react-native/Libraries/ActionSheetIOS`) - React-RCTAnimation (from `../../node_modules/react-native/Libraries/NativeAnimation`) - React-RCTBlob (from `../../node_modules/react-native/Libraries/Blob`) - React-RCTImage (from `../../node_modules/react-native/Libraries/Image`) - React-RCTLinking (from `../../node_modules/react-native/Libraries/LinkingIOS`) - React-RCTNetwork (from `../../node_modules/react-native/Libraries/Network`) - React-RCTSettings (from `../../node_modules/react-native/Libraries/Settings`) - React-RCTText (from `../../node_modules/react-native/Libraries/Text`) - React-RCTVibration (from `../../node_modules/react-native/Libraries/Vibration`) - React-runtimeexecutor (from `../../node_modules/react-native/ReactCommon/runtimeexecutor`) - ReactCommon/turbomodule/core (from `../../node_modules/react-native/ReactCommon`) - "ReactNativeART (from `../../node_modules/@react-native-community/art`)" - ReactNativeDarkMode (from `../../node_modules/react-native-dark-mode`) - ReactNativeKeyboardInput (from `../../node_modules/react-native-keyboard-input`) - ReactNativeKeyboardTrackingView (from `../../node_modules/react-native-keyboard-tracking-view`) - "RNCAsyncStorage (from `../../node_modules/@react-native-async-storage/async-storage`)" - - "RNCClipboard (from `../../node_modules/@react-native-community/clipboard`)" + - "RNCClipboard (from `../../node_modules/@react-native-clipboard/clipboard`)" - "RNCMaskedView (from `../../node_modules/@react-native-masked-view/masked-view`)" - RNDeviceInfo (from `../../node_modules/react-native-device-info`) - RNExitApp (from `../../node_modules/react-native-exit-app`) - RNFastImage (from `../../node_modules/react-native-fast-image`) - RNFS (from `../../node_modules/react-native-fs`) - RNGestureHandler (from `../../node_modules/react-native-gesture-handler`) - RNKeychain (from `../../node_modules/react-native-keychain`) - RNReanimated (from `../../node_modules/react-native-reanimated`) - RNScreens (from `../../node_modules/react-native-screens`) - RNSVG (from `../../node_modules/react-native-svg`) - RNVectorIcons (from `../../node_modules/react-native-vector-icons`) - "SQLCipher-Amalgamation (from `../../node_modules/@commapp/sqlcipher-amalgamation`)" - Yoga (from `../../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: trunk: - abseil - CocoaAsyncSocket - DVAssetLoaderDelegate - Flipper - Flipper-Boost-iOSX - Flipper-DoubleConversion - Flipper-Fmt - Flipper-Folly - Flipper-Glog - Flipper-PeerTalk - Flipper-RSocket - FlipperKit - fmt - hermes-engine - libevent - libwebp - mobile-ffmpeg-min - OpenSSL-Universal - "Protobuf-C++" - SDWebImage - SDWebImageWebPCoder - SPTPersistentCache - YogaKit EXTERNAL SOURCES: boost: :podspec: "../../node_modules/react-native/third-party-podspecs/boost.podspec" DoubleConversion: :podspec: "../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" EXApplication: :path: "../../node_modules/expo-application/ios" EXConstants: :path: "../../node_modules/expo-constants/ios" EXFileSystem: :path: "../../node_modules/expo-file-system/ios" EXFont: :path: "../../node_modules/expo-font/ios" EXHaptics: :path: "../../node_modules/expo-haptics/ios" EXImageLoader: :path: "../../node_modules/expo-image-loader/ios" EXImageManipulator: :path: "../../node_modules/expo-image-manipulator/ios" EXKeepAwake: :path: "../../node_modules/expo-keep-awake/ios" EXMediaLibrary: :path: "../../node_modules/expo-media-library/ios" Expo: :path: "../../node_modules/expo/ios" ExpoModulesCore: :path: "../../node_modules/expo-modules-core/ios" EXSecureStore: :path: "../../node_modules/expo-secure-store/ios" EXSplashScreen: :path: "../../node_modules/expo-splash-screen/ios" FBLazyVector: :path: "../../node_modules/react-native/Libraries/FBLazyVector" FBReactNativeSpec: :path: "../../node_modules/react-native/React/FBReactNativeSpec" glog: :podspec: "../../node_modules/react-native/third-party-podspecs/glog.podspec" "gRPC-C++": :podspec: "./pod-patch/.patched/gRPC-C++/1.40.0/gRPC-C++.podspec.json" gRPC-Core: :podspec: "./pod-patch/.patched/gRPC-Core/1.40.0/gRPC-Core.podspec.json" lottie-ios: :path: "../../node_modules/lottie-ios" lottie-react-native: :path: "../../node_modules/lottie-react-native" OLMKit: :path: "../../node_modules/olm" RCT-Folly: :podspec: "../../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" RCTRequired: :path: "../../node_modules/react-native/Libraries/RCTRequired" RCTTypeSafety: :path: "../../node_modules/react-native/Libraries/TypeSafety" React: :path: "../../node_modules/react-native/" React-callinvoker: :path: "../../node_modules/react-native/ReactCommon/callinvoker" React-Core: :path: "../../node_modules/react-native/" React-CoreModules: :path: "../../node_modules/react-native/React/CoreModules" React-cxxreact: :path: "../../node_modules/react-native/ReactCommon/cxxreact" React-hermes: :path: "../../node_modules/react-native/ReactCommon/hermes" React-jsi: :path: "../../node_modules/react-native/ReactCommon/jsi" React-jsiexecutor: :path: "../../node_modules/react-native/ReactCommon/jsiexecutor" React-jsinspector: :path: "../../node_modules/react-native/ReactCommon/jsinspector" React-logger: :path: "../../node_modules/react-native/ReactCommon/logger" react-native-background-upload: :path: "../../node_modules/react-native-background-upload" react-native-camera: :path: "../../node_modules/react-native-camera" react-native-ffmpeg: :podspec: "../../node_modules/react-native-ffmpeg/react-native-ffmpeg.podspec" react-native-flipper: :path: "../../node_modules/react-native-flipper" react-native-in-app-message: :path: "../../node_modules/react-native-in-app-message" react-native-netinfo: :path: "../../node_modules/@react-native-community/netinfo" react-native-notifications: :path: "../../node_modules/react-native-notifications" react-native-orientation-locker: :path: "../../node_modules/react-native-orientation-locker" react-native-pager-view: :path: "../../node_modules/react-native-pager-view" react-native-safe-area-context: :path: "../../node_modules/react-native-safe-area-context" react-native-video: :podspec: "../../node_modules/react-native-video/react-native-video.podspec" react-native-webview: :path: "../../node_modules/react-native-webview" React-perflogger: :path: "../../node_modules/react-native/ReactCommon/reactperflogger" React-RCTActionSheet: :path: "../../node_modules/react-native/Libraries/ActionSheetIOS" React-RCTAnimation: :path: "../../node_modules/react-native/Libraries/NativeAnimation" React-RCTBlob: :path: "../../node_modules/react-native/Libraries/Blob" React-RCTImage: :path: "../../node_modules/react-native/Libraries/Image" React-RCTLinking: :path: "../../node_modules/react-native/Libraries/LinkingIOS" React-RCTNetwork: :path: "../../node_modules/react-native/Libraries/Network" React-RCTSettings: :path: "../../node_modules/react-native/Libraries/Settings" React-RCTText: :path: "../../node_modules/react-native/Libraries/Text" React-RCTVibration: :path: "../../node_modules/react-native/Libraries/Vibration" React-runtimeexecutor: :path: "../../node_modules/react-native/ReactCommon/runtimeexecutor" ReactCommon: :path: "../../node_modules/react-native/ReactCommon" ReactNativeART: :path: "../../node_modules/@react-native-community/art" ReactNativeDarkMode: :path: "../../node_modules/react-native-dark-mode" ReactNativeKeyboardInput: :path: "../../node_modules/react-native-keyboard-input" ReactNativeKeyboardTrackingView: :path: "../../node_modules/react-native-keyboard-tracking-view" RNCAsyncStorage: :path: "../../node_modules/@react-native-async-storage/async-storage" RNCClipboard: - :path: "../../node_modules/@react-native-community/clipboard" + :path: "../../node_modules/@react-native-clipboard/clipboard" RNCMaskedView: :path: "../../node_modules/@react-native-masked-view/masked-view" RNDeviceInfo: :path: "../../node_modules/react-native-device-info" RNExitApp: :path: "../../node_modules/react-native-exit-app" RNFastImage: :path: "../../node_modules/react-native-fast-image" RNFS: :path: "../../node_modules/react-native-fs" RNGestureHandler: :path: "../../node_modules/react-native-gesture-handler" RNKeychain: :path: "../../node_modules/react-native-keychain" RNReanimated: :path: "../../node_modules/react-native-reanimated" RNScreens: :path: "../../node_modules/react-native-screens" RNSVG: :path: "../../node_modules/react-native-svg" RNVectorIcons: :path: "../../node_modules/react-native-vector-icons" SQLCipher-Amalgamation: :path: "../../node_modules/@commapp/sqlcipher-amalgamation" Yoga: :path: "../../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: abseil: c12cac4b0b499c3335ac47ac46adf303f0618d13 boost: a7c83b31436843459a1961bfd74b96033dc77234 CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662 DVAssetLoaderDelegate: 0caec20e4e08b8560b691131539e9180024d4bce EXApplication: 54fe5bd6268d697771645e8f1aef8b806a65247a EXConstants: 6d585d93723b18d7a8c283591a335609e3bc153e EXFileSystem: 99aac7962c11c680681819dd9cbca24e20e5b1e7 EXFont: 2597c10ac85a69d348d44d7873eccf5a7576ef5e EXHaptics: f52df335f17192e440d9639c971ebcbb3fb91dec EXImageLoader: 939451be6f7b731aaa6588920b90743f20121a4d EXImageManipulator: 49bbcede2429523edfd95dc242cf7f8fdf271307 EXKeepAwake: bf48d7f740a5cd2befed6cf9a49911d385c6c47d EXMediaLibrary: 2a684cca228d6605a72f9995d3e7b8af2a05246c Expo: f3357f1f9796d0b4d396d0be84c49933671db4ad ExpoModulesCore: c9438f6add0fb7b04b7c64eb97a833d2752a7834 EXSecureStore: 919bf7c28472862020d2cd7b59b69aae160b5d40 EXSplashScreen: 57f329dbf25c5c12800feed79068a056453dc772 FBLazyVector: a926a9aaa3596b181972abf0f47eff3dee796222 FBReactNativeSpec: f1141d5407f4a27c397bca5db03cc03919357b0d Flipper: 30e8eeeed6abdc98edaf32af0cda2f198be4b733 Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41 Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b Flipper-Folly: 83af37379faa69497529e414bd43fbfc7cae259a Flipper-Glog: 1dfd6abf1e922806c52ceb8701a3599a79a200a6 Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541 FlipperKit: d8d346844eca5d9120c17d441a2f38596e8ed2b9 fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 5337263514dd6f09803962437687240c5dc39aa4 "gRPC-C++": 3a30fb847ea1af71bea38b5c85f8fddc0ea370ba gRPC-Core: cabfc7d9b2c6ef98b9dca7ff882ddfe762750225 hermes-engine: bf7577d12ac6ccf53ab8b5af3c6ccf0dd8458c5c libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 libwebp: 98a37e597e40bfdb4c911fc98f2c53d0b12d05fc lottie-ios: 48fac6be217c76937e36e340e2d09cf7b10b7f5f lottie-react-native: 4dff8fe8d10ddef9e7880e770080f4a56121397e mobile-ffmpeg-min: d5d22dcef5c8ec56f771258f1f5be245d914f193 OLMKit: a15f216aa14ba199b4fd827b3d7ef04629b56636 OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b "Protobuf-C++": 8833c36ca1a3b6422e75ec27534d63a6a762c843 RCT-Folly: 632694a4b94fb0f2cb090921861846beec77d8b8 RCTRequired: 405e24508a0feed1771d48caebb85c581db53122 RCTTypeSafety: 0654998ea6afd3dccecbf6bb379d7c10d1361a72 React: cce3ac45191e66a78c79234582cbfe322e4dfd00 React-callinvoker: 613b19264ce63cab0a2bbb6546caa24f2ad0a679 React-Core: fe529d7c1d74b3eb9505fdfc2f4b10f2f2984a85 React-CoreModules: 71f5d032922a043ab6f9023acda41371a774bf5c React-cxxreact: 808c0d39b270860af712848082009d623180999c React-hermes: 6d7dfec2394c40780f5db123acf7a4ae2cc01895 React-jsi: 01b246df3667ad921a33adeb0ce199772afe9e2b React-jsiexecutor: 50a73168582868421112609d2fb155e607e34ec8 React-jsinspector: 953260b8580780a6e81f2a6d319a8d42fd5028d8 React-logger: fa4ff1e9c7e115648f7c5dafb7c20822ab4f7a7e react-native-background-upload: c62f25610ffd49b1781fbdf1135b3b17f2f914b9 react-native-camera: b5c8c7a71feecfdd5b39f0dbbf6b64b957ed55f2 react-native-ffmpeg: f9a60452aaa5d478aac205b248224994f3bde416 react-native-flipper: 80b71629f5bf7b942dfae7af0c5f88526d19b3ca react-native-in-app-message: f91de5009620af01456531118264c93e249b83ec react-native-netinfo: e849fc21ca2f4128a5726c801a82fc6f4a6db50d react-native-notifications: bb042206ac7eab9323d528c780b3d6fe796c1f5e react-native-orientation-locker: 23918c400376a7043e752c639c122fcf6bce8f1c react-native-pager-view: 3051346698a0ba0c4e13e40097cc11b00ee03cca react-native-safe-area-context: b6e0e284002381d2ff29fa4fff42b4d8282e3c94 react-native-video: 0bb76b6d6b77da3009611586c7dbf817b947f30e react-native-webview: e771bc375f789ebfa02a26939a57dbc6fa897336 React-perflogger: 169fb34f60c5fd793b370002ee9c916eba9bc4ae React-RCTActionSheet: 2355539e02ad5cd4b1328682ab046487e1e1e920 React-RCTAnimation: 150644a38c24d80f1f761859c10c727412303f57 React-RCTBlob: 66042a0ab4206f112ed453130f2cb8802dd7cd82 React-RCTImage: 3b954d8398ec4bed26cec10e10d311cb3533818b React-RCTLinking: 331d9b8a0702c751c7843ddc65b64297c264adc2 React-RCTNetwork: 96e10dad824ce112087445199ea734b79791ad14 React-RCTSettings: 41feb3f5fb3319846ad0ba9e8d339e54b5774b67 React-RCTText: 254741e11c41516759e93ab0b8c38b90f8998f61 React-RCTVibration: 96dbefca7504f3e52ff47cd0ad0826d20e3a789f React-runtimeexecutor: 09041c28ce04143a113eac2d357a6b06bd64b607 ReactCommon: 8a7a138ae43c04bb8dd760935589f326ca810484 ReactNativeART: 78edc68dd4a1e675338cd0cd113319cf3a65f2ab ReactNativeDarkMode: 88317ff05ba95fd063dd347ad32f8c4cefd3166c ReactNativeKeyboardInput: 266ba27a2e9921f5bdc0b4cc30289b2a2f46b157 ReactNativeKeyboardTrackingView: 02137fac3b2ebd330d74fa54ead48b14750a2306 RNCAsyncStorage: 0c357f3156fcb16c8589ede67cc036330b6698ca - RNCClipboard: f470a4445c779f99c10201b038ab3f9e24e71dbc + RNCClipboard: f66930407a30948ffdecf43a2459bcf05aa59804 RNCMaskedView: bc0170f389056201c82a55e242e5d90070e18e5a RNDeviceInfo: 55463fa6e252ca3f0e2ba6001a7b82f879914338 RNExitApp: c4e052df2568b43bec8a37c7cd61194d4cfee2c3 RNFastImage: 2ed80661d5ef384fb1b539f1f3c81a1733f92bc9 RNFS: 54da03c2b7d862c42ea3ca8c7f86f892760a535a RNGestureHandler: a479ebd5ed4221a810967000735517df0d2db211 RNKeychain: 4f63aada75ebafd26f4bc2c670199461eab85d94 RNReanimated: f9055ab75a49358b30f99155637f95d77727e7dc RNScreens: 6e1ea5787989f92b0671049b808aef64fa1ef98c RNSVG: 302bfc9905bd8122f08966dc2ce2d07b7b52b9f8 RNVectorIcons: 0bb4def82230be1333ddaeee9fcba45f0b288ed4 SDWebImage: 0905f1b7760fc8ac4198cae0036600d67478751e SDWebImageWebPCoder: d0dac55073088d24b2ac1b191a71a8f8d0adac21 SPTPersistentCache: df36ea46762d7cf026502bbb86a8b79d0080dff4 SQLCipher-Amalgamation: cbd36045fe7b458b8a442958a01aefdbc44c20f8 Yoga: b316a990bb6d115afa1b436b5626ac7c61717d17 YogaKit: f782866e155069a2cca2517aafea43200b01fd5a PODFILE CHECKSUM: 4941a5495075fdda98e5a2f416bf6315c8111946 COCOAPODS: 1.11.3 diff --git a/native/media/image-modal.react.js b/native/media/image-modal.react.js index b9132b17e..7e700979e 100644 --- a/native/media/image-modal.react.js +++ b/native/media/image-modal.react.js @@ -1,1280 +1,1280 @@ // @flow -import Clipboard from '@react-native-community/clipboard'; +import Clipboard from '@react-native-clipboard/clipboard'; import invariant from 'invariant'; import * as React from 'react'; import { View, Text, StyleSheet, TouchableOpacity, Platform, } from 'react-native'; import { PinchGestureHandler, PanGestureHandler, TapGestureHandler, State as GestureState, } from 'react-native-gesture-handler'; import Orientation from 'react-native-orientation-locker'; import Animated from 'react-native-reanimated'; import { type MediaInfo, type Dimensions } from 'lib/types/media-types'; import { useIsReportEnabled } from 'lib/utils/report-utils'; import SWMansionIcon from '../components/swmansion-icon.react'; import ConnectedStatusBar from '../connected-status-bar.react'; import { displayActionResultModal } from '../navigation/action-result-modal'; import type { AppNavigationProp } from '../navigation/app-navigator.react'; import { OverlayContext, type OverlayContextType, } from '../navigation/overlay-context'; import type { NavigationRoute } from '../navigation/route-names'; import { useSelector } from '../redux/redux-utils'; import { type DerivedDimensionsInfo, derivedDimensionsInfoSelector, } from '../selectors/dimensions-selectors'; import type { ChatMultimediaMessageInfoItem } from '../types/chat-types'; import { type VerticalBounds, type LayoutCoordinates, } from '../types/layout-types'; import type { NativeMethods } from '../types/react-native'; import { clamp, gestureJustStarted, gestureJustEnded, runTiming, } from '../utils/animation-utils'; import Multimedia from './multimedia.react'; import { intentionalSaveMedia } from './save-media'; /* eslint-disable import/no-named-as-default-member */ const { Value, Node, Clock, event, Extrapolate, block, set, call, cond, not, and, or, eq, neq, greaterThan, lessThan, add, sub, multiply, divide, pow, max, min, round, abs, interpolateNode, startClock, stopClock, clockRunning, decay, } = Animated; /* eslint-enable import/no-named-as-default-member */ function scaleDelta(value: Node, gestureActive: Node): Node { const diffThisFrame = new Value(1); const prevValue = new Value(1); return cond( gestureActive, [ set(diffThisFrame, divide(value, prevValue)), set(prevValue, value), diffThisFrame, ], set(prevValue, 1), ); } function panDelta(value: Node, gestureActive: Node): Node { const diffThisFrame = new Value(0); const prevValue = new Value(0); return cond( gestureActive, [ set(diffThisFrame, sub(value, prevValue)), set(prevValue, value), diffThisFrame, ], set(prevValue, 0), ); } function runDecay( clock: Clock, velocity: Node, initialPosition: Node, startStopClock: boolean = true, ): Node { const state = { finished: new Value(0), velocity: new Value(0), position: new Value(0), time: new Value(0), }; const config = { deceleration: 0.99 }; return block([ cond(not(clockRunning(clock)), [ set(state.finished, 0), set(state.velocity, velocity), set(state.position, initialPosition), set(state.time, 0), startStopClock ? startClock(clock) : undefined, ]), decay(clock, state, config), cond(state.finished, startStopClock ? stopClock(clock) : undefined), state.position, ]); } export type ImageModalParams = { +presentedFrom: string, +mediaInfo: MediaInfo, +initialCoordinates: LayoutCoordinates, +verticalBounds: VerticalBounds, +item: ChatMultimediaMessageInfoItem, }; type TouchableOpacityInstance = React.AbstractComponent< React.ElementConfig, NativeMethods, >; type BaseProps = { +navigation: AppNavigationProp<'ImageModal'>, +route: NavigationRoute<'ImageModal'>, }; type Props = { ...BaseProps, // Redux state +dimensions: DerivedDimensionsInfo, // withOverlayContext +overlayContext: ?OverlayContextType, +mediaReportsEnabled: boolean, }; type State = { +closeButtonEnabled: boolean, +actionLinksEnabled: boolean, }; class ImageModal extends React.PureComponent { state: State = { closeButtonEnabled: true, actionLinksEnabled: true, }; closeButton: ?React.ElementRef; mediaIconsContainer: ?React.ElementRef; closeButtonX = new Value(-1); closeButtonY = new Value(-1); closeButtonWidth = new Value(0); closeButtonHeight = new Value(0); closeButtonLastState = new Value(1); mediaIconsX = new Value(-1); mediaIconsY = new Value(-1); mediaIconsWidth = new Value(0); mediaIconsHeight = new Value(0); actionLinksLastState = new Value(1); centerX: Value; centerY: Value; frameWidth: Value; frameHeight: Value; imageWidth: Value; imageHeight: Value; pinchHandler = React.createRef(); panHandler = React.createRef(); singleTapHandler = React.createRef(); doubleTapHandler = React.createRef(); handlerRefs = [ this.pinchHandler, this.panHandler, this.singleTapHandler, this.doubleTapHandler, ]; beforeDoubleTapRefs; beforeSingleTapRefs; pinchEvent; panEvent; singleTapEvent; doubleTapEvent; scale: Node; x: Node; y: Node; backdropOpacity: Node; imageContainerOpacity: Node; actionLinksOpacity: Node; closeButtonOpacity: Node; constructor(props: Props) { super(props); this.updateDimensions(); const { imageWidth, imageHeight } = this; const left = sub(this.centerX, divide(imageWidth, 2)); const top = sub(this.centerY, divide(imageHeight, 2)); const { initialCoordinates } = props.route.params; const initialScale = divide(initialCoordinates.width, imageWidth); const initialTranslateX = sub( initialCoordinates.x + initialCoordinates.width / 2, add(left, divide(imageWidth, 2)), ); const initialTranslateY = sub( initialCoordinates.y + initialCoordinates.height / 2, add(top, divide(imageHeight, 2)), ); const { overlayContext } = props; invariant(overlayContext, 'ImageModal should have OverlayContext'); const navigationProgress = overlayContext.position; // The inputs we receive from PanGestureHandler const panState = new Value(-1); const panTranslationX = new Value(0); const panTranslationY = new Value(0); const panVelocityX = new Value(0); const panVelocityY = new Value(0); const panAbsoluteX = new Value(0); const panAbsoluteY = new Value(0); this.panEvent = event([ { nativeEvent: { state: panState, translationX: panTranslationX, translationY: panTranslationY, velocityX: panVelocityX, velocityY: panVelocityY, absoluteX: panAbsoluteX, absoluteY: panAbsoluteY, }, }, ]); const curPanActive = new Value(0); const panActive = block([ cond( and( gestureJustStarted(panState), this.outsideButtons( sub(panAbsoluteX, panTranslationX), sub(panAbsoluteY, panTranslationY), ), ), set(curPanActive, 1), ), cond(gestureJustEnded(panState), set(curPanActive, 0)), curPanActive, ]); const lastPanActive = new Value(0); const panJustEnded = cond(eq(lastPanActive, panActive), 0, [ set(lastPanActive, panActive), eq(panActive, 0), ]); // The inputs we receive from PinchGestureHandler const pinchState = new Value(-1); const pinchScale = new Value(1); const pinchFocalX = new Value(0); const pinchFocalY = new Value(0); this.pinchEvent = event([ { nativeEvent: { state: pinchState, scale: pinchScale, focalX: pinchFocalX, focalY: pinchFocalY, }, }, ]); const pinchActive = eq(pinchState, GestureState.ACTIVE); // The inputs we receive from single TapGestureHandler const singleTapState = new Value(-1); const singleTapX = new Value(0); const singleTapY = new Value(0); this.singleTapEvent = event([ { nativeEvent: { state: singleTapState, x: singleTapX, y: singleTapY, }, }, ]); // The inputs we receive from double TapGestureHandler const doubleTapState = new Value(-1); const doubleTapX = new Value(0); const doubleTapY = new Value(0); this.doubleTapEvent = event([ { nativeEvent: { state: doubleTapState, x: doubleTapX, y: doubleTapY, }, }, ]); // The all-important outputs const curScale = new Value(1); const curX = new Value(0); const curY = new Value(0); const curBackdropOpacity = new Value(1); const curCloseButtonOpacity = new Value(1); const curActionLinksOpacity = new Value(1); // The centered variables help us know if we need to be recentered const recenteredScale = max(curScale, 1); const horizontalPanSpace = this.horizontalPanSpace(recenteredScale); const verticalPanSpace = this.verticalPanSpace(recenteredScale); const resetXClock = new Clock(); const resetYClock = new Clock(); const zoomClock = new Clock(); const dismissingFromPan = new Value(0); const roundedCurScale = divide(round(multiply(curScale, 1000)), 1000); const gestureActive = or(pinchActive, panActive); const activeInteraction = or( gestureActive, clockRunning(zoomClock), dismissingFromPan, ); const updates = [ this.pinchUpdate( pinchActive, pinchScale, pinchFocalX, pinchFocalY, curScale, curX, curY, ), this.panUpdate(panActive, panTranslationX, panTranslationY, curX, curY), this.singleTapUpdate( singleTapState, singleTapX, singleTapY, roundedCurScale, curCloseButtonOpacity, curActionLinksOpacity, ), this.doubleTapUpdate( doubleTapState, doubleTapX, doubleTapY, roundedCurScale, zoomClock, gestureActive, curScale, curX, curY, ), this.backdropOpacityUpdate( panJustEnded, pinchActive, panVelocityX, panVelocityY, roundedCurScale, curX, curY, curBackdropOpacity, dismissingFromPan, ), this.recenter( resetXClock, resetYClock, activeInteraction, recenteredScale, horizontalPanSpace, verticalPanSpace, curScale, curX, curY, ), this.flingUpdate( resetXClock, resetYClock, activeInteraction, panJustEnded, panVelocityX, panVelocityY, horizontalPanSpace, verticalPanSpace, curX, curY, ), ]; const updatedScale = [updates, curScale]; const updatedCurX = [updates, curX]; const updatedCurY = [updates, curY]; const updatedBackdropOpacity = [updates, curBackdropOpacity]; const updatedCloseButtonOpacity = [updates, curCloseButtonOpacity]; const updatedActionLinksOpacity = [updates, curActionLinksOpacity]; const reverseNavigationProgress = sub(1, navigationProgress); this.scale = add( multiply(reverseNavigationProgress, initialScale), multiply(navigationProgress, updatedScale), ); this.x = add( multiply(reverseNavigationProgress, initialTranslateX), multiply(navigationProgress, updatedCurX), ); this.y = add( multiply(reverseNavigationProgress, initialTranslateY), multiply(navigationProgress, updatedCurY), ); this.backdropOpacity = multiply(navigationProgress, updatedBackdropOpacity); this.imageContainerOpacity = interpolateNode(navigationProgress, { inputRange: [0, 0.1], outputRange: [0, 1], extrapolate: Extrapolate.CLAMP, }); const buttonOpacity = interpolateNode(updatedBackdropOpacity, { inputRange: [0.95, 1], outputRange: [0, 1], extrapolate: Extrapolate.CLAMP, }); this.closeButtonOpacity = multiply( navigationProgress, buttonOpacity, updatedCloseButtonOpacity, ); this.actionLinksOpacity = multiply( navigationProgress, buttonOpacity, updatedActionLinksOpacity, ); this.beforeDoubleTapRefs = Platform.select({ android: [], default: [this.pinchHandler, this.panHandler], }); this.beforeSingleTapRefs = [ ...this.beforeDoubleTapRefs, this.doubleTapHandler, ]; } // How much space do we have to pan the image horizontally? horizontalPanSpace(scale: Node): Node { const apparentWidth = multiply(this.imageWidth, scale); const horizPop = divide(sub(apparentWidth, this.frameWidth), 2); return max(horizPop, 0); } // How much space do we have to pan the image vertically? verticalPanSpace(scale: Node): Node { const apparentHeight = multiply(this.imageHeight, scale); const vertPop = divide(sub(apparentHeight, this.frameHeight), 2); return max(vertPop, 0); } pinchUpdate( // Inputs pinchActive: Node, pinchScale: Node, pinchFocalX: Node, pinchFocalY: Node, // Outputs curScale: Value, curX: Value, curY: Value, ): Node { const deltaScale = scaleDelta(pinchScale, pinchActive); const deltaPinchX = multiply( sub(1, deltaScale), sub(pinchFocalX, curX, this.centerX), ); const deltaPinchY = multiply( sub(1, deltaScale), sub(pinchFocalY, curY, this.centerY), ); return cond( [deltaScale, pinchActive], [ set(curX, add(curX, deltaPinchX)), set(curY, add(curY, deltaPinchY)), set(curScale, multiply(curScale, deltaScale)), ], ); } outsideButtons(x: Node, y: Node): Node { const { closeButtonX, closeButtonY, closeButtonWidth, closeButtonHeight, closeButtonLastState, mediaIconsX, mediaIconsY, mediaIconsWidth, mediaIconsHeight, actionLinksLastState, } = this; return and( or( eq(closeButtonLastState, 0), lessThan(x, closeButtonX), greaterThan(x, add(closeButtonX, closeButtonWidth)), lessThan(y, closeButtonY), greaterThan(y, add(closeButtonY, closeButtonHeight)), ), or( eq(actionLinksLastState, 0), lessThan(x, mediaIconsX), greaterThan(x, add(mediaIconsX, mediaIconsWidth)), lessThan(y, mediaIconsY), greaterThan(y, add(mediaIconsY, mediaIconsHeight)), ), ); } panUpdate( // Inputs panActive: Node, panTranslationX: Node, panTranslationY: Node, // Outputs curX: Value, curY: Value, ): Node { const deltaX = panDelta(panTranslationX, panActive); const deltaY = panDelta(panTranslationY, panActive); return cond( [deltaX, deltaY, panActive], [set(curX, add(curX, deltaX)), set(curY, add(curY, deltaY))], ); } singleTapUpdate( // Inputs singleTapState: Node, singleTapX: Node, singleTapY: Node, roundedCurScale: Node, // Outputs curCloseButtonOpacity: Value, curActionLinksOpacity: Value, ): Node { const lastTapX = new Value(0); const lastTapY = new Value(0); const fingerJustReleased = and( gestureJustEnded(singleTapState), this.outsideButtons(lastTapX, lastTapY), ); const wasZoomed = new Value(0); const isZoomed = greaterThan(roundedCurScale, 1); const becameUnzoomed = and(wasZoomed, not(isZoomed)); const closeButtonState = cond( or( fingerJustReleased, and(becameUnzoomed, eq(this.closeButtonLastState, 0)), ), sub(1, this.closeButtonLastState), this.closeButtonLastState, ); const actionLinksState = cond( isZoomed, 0, cond( or(fingerJustReleased, becameUnzoomed), sub(1, this.actionLinksLastState), this.actionLinksLastState, ), ); const closeButtonAppearClock = new Clock(); const closeButtonDisappearClock = new Clock(); const actionLinksAppearClock = new Clock(); const actionLinksDisappearClock = new Clock(); return block([ fingerJustReleased, set( curCloseButtonOpacity, cond( eq(closeButtonState, 1), [ stopClock(closeButtonDisappearClock), runTiming(closeButtonAppearClock, curCloseButtonOpacity, 1), ], [ stopClock(closeButtonAppearClock), runTiming(closeButtonDisappearClock, curCloseButtonOpacity, 0), ], ), ), set( curActionLinksOpacity, cond( eq(actionLinksState, 1), [ stopClock(actionLinksDisappearClock), runTiming(actionLinksAppearClock, curActionLinksOpacity, 1), ], [ stopClock(actionLinksAppearClock), runTiming(actionLinksDisappearClock, curActionLinksOpacity, 0), ], ), ), set(this.actionLinksLastState, actionLinksState), set(this.closeButtonLastState, closeButtonState), set(wasZoomed, isZoomed), set(lastTapX, singleTapX), set(lastTapY, singleTapY), call([eq(curCloseButtonOpacity, 1)], this.setCloseButtonEnabled), call([eq(curActionLinksOpacity, 1)], this.setActionLinksEnabled), ]); } doubleTapUpdate( // Inputs doubleTapState: Node, doubleTapX: Node, doubleTapY: Node, roundedCurScale: Node, zoomClock: Clock, gestureActive: Node, // Outputs curScale: Value, curX: Value, curY: Value, ): Node { const zoomClockRunning = clockRunning(zoomClock); const zoomActive = and(not(gestureActive), zoomClockRunning); const targetScale = cond(greaterThan(roundedCurScale, 1), 1, 3); const tapXDiff = sub(doubleTapX, this.centerX, curX); const tapYDiff = sub(doubleTapY, this.centerY, curY); const tapXPercent = divide(tapXDiff, this.imageWidth, curScale); const tapYPercent = divide(tapYDiff, this.imageHeight, curScale); const horizPanSpace = this.horizontalPanSpace(targetScale); const vertPanSpace = this.verticalPanSpace(targetScale); const horizPanPercent = divide(horizPanSpace, this.imageWidth, targetScale); const vertPanPercent = divide(vertPanSpace, this.imageHeight, targetScale); const tapXPercentClamped = clamp( tapXPercent, multiply(-1, horizPanPercent), horizPanPercent, ); const tapYPercentClamped = clamp( tapYPercent, multiply(-1, vertPanPercent), vertPanPercent, ); const targetX = multiply(tapXPercentClamped, this.imageWidth, targetScale); const targetY = multiply(tapYPercentClamped, this.imageHeight, targetScale); const targetRelativeScale = divide(targetScale, curScale); const targetRelativeX = multiply(-1, add(targetX, curX)); const targetRelativeY = multiply(-1, add(targetY, curY)); const zoomScale = runTiming(zoomClock, 1, targetRelativeScale); const zoomX = runTiming(zoomClock, 0, targetRelativeX, false); const zoomY = runTiming(zoomClock, 0, targetRelativeY, false); const deltaScale = scaleDelta(zoomScale, zoomActive); const deltaX = panDelta(zoomX, zoomActive); const deltaY = panDelta(zoomY, zoomActive); const fingerJustReleased = and( gestureJustEnded(doubleTapState), this.outsideButtons(doubleTapX, doubleTapY), ); return cond( [fingerJustReleased, deltaX, deltaY, deltaScale, gestureActive], stopClock(zoomClock), cond(or(zoomClockRunning, fingerJustReleased), [ zoomX, zoomY, zoomScale, set(curX, add(curX, deltaX)), set(curY, add(curY, deltaY)), set(curScale, multiply(curScale, deltaScale)), ]), ); } backdropOpacityUpdate( // Inputs panJustEnded: Node, pinchActive: Node, panVelocityX: Node, panVelocityY: Node, roundedCurScale: Node, // Outputs curX: Value, curY: Value, curBackdropOpacity: Value, dismissingFromPan: Value, ): Node { const progressiveOpacity = max( min( sub(1, abs(divide(curX, this.frameWidth))), sub(1, abs(divide(curY, this.frameHeight))), ), 0, ); const resetClock = new Clock(); const velocity = pow(add(pow(panVelocityX, 2), pow(panVelocityY, 2)), 0.5); const shouldGoBack = and( panJustEnded, or(greaterThan(velocity, 50), greaterThan(0.7, progressiveOpacity)), ); const decayClock = new Clock(); const decayItems = [ set(curX, runDecay(decayClock, panVelocityX, curX, false)), set(curY, runDecay(decayClock, panVelocityY, curY)), ]; return cond( [panJustEnded, dismissingFromPan], decayItems, cond( or(pinchActive, greaterThan(roundedCurScale, 1)), set(curBackdropOpacity, runTiming(resetClock, curBackdropOpacity, 1)), [ stopClock(resetClock), set(curBackdropOpacity, progressiveOpacity), set(dismissingFromPan, shouldGoBack), cond(shouldGoBack, [decayItems, call([], this.close)]), ], ), ); } recenter( // Inputs resetXClock: Clock, resetYClock: Clock, activeInteraction: Node, recenteredScale: Node, horizontalPanSpace: Node, verticalPanSpace: Node, // Outputs curScale: Value, curX: Value, curY: Value, ): Node { const resetScaleClock = new Clock(); const recenteredX = clamp( curX, multiply(-1, horizontalPanSpace), horizontalPanSpace, ); const recenteredY = clamp( curY, multiply(-1, verticalPanSpace), verticalPanSpace, ); return cond( activeInteraction, [ stopClock(resetScaleClock), stopClock(resetXClock), stopClock(resetYClock), ], [ cond( or(clockRunning(resetScaleClock), neq(recenteredScale, curScale)), set(curScale, runTiming(resetScaleClock, curScale, recenteredScale)), ), cond( or(clockRunning(resetXClock), neq(recenteredX, curX)), set(curX, runTiming(resetXClock, curX, recenteredX)), ), cond( or(clockRunning(resetYClock), neq(recenteredY, curY)), set(curY, runTiming(resetYClock, curY, recenteredY)), ), ], ); } flingUpdate( // Inputs resetXClock: Clock, resetYClock: Clock, activeInteraction: Node, panJustEnded: Node, panVelocityX: Node, panVelocityY: Node, horizontalPanSpace: Node, verticalPanSpace: Node, // Outputs curX: Value, curY: Value, ): Node { const flingXClock = new Clock(); const flingYClock = new Clock(); const decayX = runDecay(flingXClock, panVelocityX, curX); const recenteredX = clamp( decayX, multiply(-1, horizontalPanSpace), horizontalPanSpace, ); const decayY = runDecay(flingYClock, panVelocityY, curY); const recenteredY = clamp( decayY, multiply(-1, verticalPanSpace), verticalPanSpace, ); return cond( activeInteraction, [stopClock(flingXClock), stopClock(flingYClock)], [ cond( clockRunning(resetXClock), stopClock(flingXClock), cond(or(panJustEnded, clockRunning(flingXClock)), [ set(curX, recenteredX), cond(neq(decayX, recenteredX), stopClock(flingXClock)), ]), ), cond( clockRunning(resetYClock), stopClock(flingYClock), cond(or(panJustEnded, clockRunning(flingYClock)), [ set(curY, recenteredY), cond(neq(decayY, recenteredY), stopClock(flingYClock)), ]), ), ], ); } updateDimensions() { const { width: frameWidth, height: frameHeight } = this.frame; const { topInset } = this.props.dimensions; if (this.frameWidth) { this.frameWidth.setValue(frameWidth); } else { this.frameWidth = new Value(frameWidth); } if (this.frameHeight) { this.frameHeight.setValue(frameHeight); } else { this.frameHeight = new Value(frameHeight); } const centerX = frameWidth / 2; const centerY = frameHeight / 2 + topInset; if (this.centerX) { this.centerX.setValue(centerX); } else { this.centerX = new Value(centerX); } if (this.centerY) { this.centerY.setValue(centerY); } else { this.centerY = new Value(centerY); } const { width, height } = this.imageDimensions; if (this.imageWidth) { this.imageWidth.setValue(width); } else { this.imageWidth = new Value(width); } if (this.imageHeight) { this.imageHeight.setValue(height); } else { this.imageHeight = new Value(height); } } componentDidMount() { if (ImageModal.isActive(this.props)) { Orientation.unlockAllOrientations(); } } componentWillUnmount() { if (ImageModal.isActive(this.props)) { Orientation.lockToPortrait(); } } componentDidUpdate(prevProps: Props) { if (this.props.dimensions !== prevProps.dimensions) { this.updateDimensions(); } const isActive = ImageModal.isActive(this.props); const wasActive = ImageModal.isActive(prevProps); if (isActive && !wasActive) { Orientation.unlockAllOrientations(); } else if (!isActive && wasActive) { Orientation.lockToPortrait(); } } get frame(): Dimensions { const { width, safeAreaHeight } = this.props.dimensions; return { width, height: safeAreaHeight }; } get imageDimensions(): Dimensions { // Make space for the close button let { height: maxHeight, width: maxWidth } = this.frame; if (maxHeight > maxWidth) { maxHeight -= 100; } else { maxWidth -= 100; } const { dimensions } = this.props.route.params.mediaInfo; if (dimensions.height < maxHeight && dimensions.width < maxWidth) { return dimensions; } const heightRatio = maxHeight / dimensions.height; const widthRatio = maxWidth / dimensions.width; if (heightRatio < widthRatio) { return { height: maxHeight, width: dimensions.width * heightRatio, }; } else { return { width: maxWidth, height: dimensions.height * widthRatio, }; } } get imageContainerStyle() { const { height, width } = this.imageDimensions; const { height: frameHeight, width: frameWidth } = this.frame; const top = (frameHeight - height) / 2 + this.props.dimensions.topInset; const left = (frameWidth - width) / 2; const { verticalBounds } = this.props.route.params; return { height, width, marginTop: top - verticalBounds.y, marginLeft: left, opacity: this.imageContainerOpacity, transform: [ { translateX: this.x }, { translateY: this.y }, { scale: this.scale }, ], }; } static isActive(props) { const { overlayContext } = props; invariant(overlayContext, 'ImageModal should have OverlayContext'); return !overlayContext.isDismissing; } get contentContainerStyle() { const { verticalBounds } = this.props.route.params; const fullScreenHeight = this.props.dimensions.height; const top = verticalBounds.y; const bottom = fullScreenHeight - verticalBounds.y - verticalBounds.height; // margin will clip, but padding won't const verticalStyle = ImageModal.isActive(this.props) ? { paddingTop: top, paddingBottom: bottom } : { marginTop: top, marginBottom: bottom }; return [styles.contentContainer, verticalStyle]; } render() { const { mediaInfo } = this.props.route.params; const statusBar = ImageModal.isActive(this.props) ? (