From 08d357d0a9187f03c2810fe1f39221379319ffdd Mon Sep 17 00:00:00 2001 From: Vit Horacek Date: Mon, 11 Mar 2024 18:08:25 +0000 Subject: [PATCH 1/3] Revert "Merge pull request #32336 from callstack-internal/hur/perf/chat-switch" This reverts commit 54040182bc629f3c366d58103a955eced2731e54, reversing changes made to 4ada067c0374caa2a7ef9677d7bbffca13b0e171. --- src/components/FlatList/index.android.tsx | 11 ++- src/components/HeaderWithBackButton/types.ts | 7 +- .../InvertedFlatList/BaseInvertedFlatList.tsx | 10 +-- .../LHNOptionsList/LHNOptionsList.tsx | 65 ++++++++------- .../LHNOptionsList/OptionRowLHNData.tsx | 5 +- src/components/LHNOptionsList/types.ts | 3 +- src/components/MoneyReportHeader.tsx | 3 + src/components/MoneyRequestHeader.tsx | 3 + src/libs/Pusher/pusher.ts | 81 +++++++++---------- src/libs/actions/Report.ts | 12 --- src/pages/home/ReportScreen.tsx | 30 +++---- .../ComposerWithSuggestions.tsx | 19 +++-- .../SilentCommentUpdater/index.tsx | 10 --- src/pages/home/report/ReportActionsList.tsx | 10 +-- src/pages/home/report/ReportActionsView.tsx | 22 +---- src/pages/home/sidebar/SidebarLinks.js | 4 +- 16 files changed, 122 insertions(+), 173 deletions(-) diff --git a/src/components/FlatList/index.android.tsx b/src/components/FlatList/index.android.tsx index 1246367d29e8..863930203863 100644 --- a/src/components/FlatList/index.android.tsx +++ b/src/components/FlatList/index.android.tsx @@ -1,7 +1,7 @@ import {useFocusEffect} from '@react-navigation/native'; import type {ForwardedRef} from 'react'; import React, {forwardRef, useCallback, useContext} from 'react'; -import type {FlatListProps, NativeScrollEvent, NativeSyntheticEvent} from 'react-native'; +import type {FlatListProps} from 'react-native'; import {FlatList} from 'react-native'; import {ActionListContext} from '@pages/home/ReportScreenContext'; @@ -22,9 +22,6 @@ function CustomFlatList(props: FlatListProps, ref: ForwardedRef) } }, [scrollPosition?.offset, ref]); - // eslint-disable-next-line react-hooks/exhaustive-deps - const onMomentumScrollEnd = useCallback((event: NativeSyntheticEvent) => setScrollPosition({offset: event.nativeEvent.contentOffset.y}), []); - useFocusEffect( useCallback(() => { onScreenFocus(); @@ -35,8 +32,10 @@ function CustomFlatList(props: FlatListProps, ref: ForwardedRef) // eslint-disable-next-line react/jsx-props-no-spreading {...props} - onScroll={props.onScroll} - onMomentumScrollEnd={onMomentumScrollEnd} + onScroll={(event) => props.onScroll?.(event)} + onMomentumScrollEnd={(event) => { + setScrollPosition({offset: event.nativeEvent.contentOffset.y}); + }} ref={ref} /> ); diff --git a/src/components/HeaderWithBackButton/types.ts b/src/components/HeaderWithBackButton/types.ts index c3ffb500080b..83afbad8636b 100644 --- a/src/components/HeaderWithBackButton/types.ts +++ b/src/components/HeaderWithBackButton/types.ts @@ -1,9 +1,9 @@ import type {ReactNode} from 'react'; -import type {OnyxEntry} from 'react-native-onyx'; +import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import type {Action} from '@hooks/useSingleExecution'; import type {StepCounterParams} from '@src/languages/types'; import type {AnchorPosition} from '@src/styles'; -import type {Policy, Report} from '@src/types/onyx'; +import type {PersonalDetails, Policy, Report} from '@src/types/onyx'; import type ChildrenProps from '@src/types/utils/ChildrenProps'; import type IconAsset from '@src/types/utils/IconAsset'; @@ -101,6 +101,9 @@ type HeaderWithBackButtonProps = Partial & { /** The report's policy, if we're showing the details for a report and need info about it for AvatarWithDisplay */ policy?: OnyxEntry; + /** Policies, if we're showing the details for a report and need participant details for AvatarWithDisplay */ + personalDetails?: OnyxCollection; + /** Single execution function to prevent concurrent navigation actions */ singleExecution?: (action: Action) => Action; diff --git a/src/components/InvertedFlatList/BaseInvertedFlatList.tsx b/src/components/InvertedFlatList/BaseInvertedFlatList.tsx index 0549e19c2eb4..e28400505280 100644 --- a/src/components/InvertedFlatList/BaseInvertedFlatList.tsx +++ b/src/components/InvertedFlatList/BaseInvertedFlatList.tsx @@ -6,11 +6,6 @@ import FlatList from '@components/FlatList'; const WINDOW_SIZE = 15; const AUTOSCROLL_TO_TOP_THRESHOLD = 128; -const maintainVisibleContentPosition = { - minIndexForVisible: 0, - autoscrollToTopThreshold: AUTOSCROLL_TO_TOP_THRESHOLD, -}; - function BaseInvertedFlatList(props: FlatListProps, ref: ForwardedRef) { return ( (props: FlatListProps, ref: ForwardedRef ); diff --git a/src/components/LHNOptionsList/LHNOptionsList.tsx b/src/components/LHNOptionsList/LHNOptionsList.tsx index 93eac30d5477..f5545f402b14 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.tsx +++ b/src/components/LHNOptionsList/LHNOptionsList.tsx @@ -1,8 +1,9 @@ import {FlashList} from '@shopify/flash-list'; import type {ReactElement} from 'react'; -import React, {memo, useCallback, useMemo} from 'react'; +import React, {memo, useCallback} from 'react'; import {StyleSheet, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; +import withCurrentReportID from '@components/withCurrentReportID'; import usePermissions from '@hooks/usePermissions'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; @@ -27,6 +28,7 @@ function LHNOptionsList({ preferredLocale = CONST.LOCALES.DEFAULT, personalDetails = {}, transactions = {}, + currentReportID = '', draftComments = {}, transactionViolations = {}, onFirstItemRendered = () => {}, @@ -84,7 +86,7 @@ function LHNOptionsList({ lastReportActionTransaction={lastReportActionTransaction} receiptTransactions={transactions} viewMode={optionMode} - isFocused={!shouldDisableFocusOptions} + isFocused={!shouldDisableFocusOptions && reportID === currentReportID} onSelectRow={onSelectRow} preferredLocale={preferredLocale} comment={itemComment} @@ -96,6 +98,7 @@ function LHNOptionsList({ ); }, [ + currentReportID, draftComments, onSelectRow, optionMode, @@ -113,8 +116,6 @@ function LHNOptionsList({ ], ); - const extraData = useMemo(() => [reportActions, reports, policy, personalDetails], [reportActions, reports, policy, personalDetails]); - return ( @@ -135,31 +136,33 @@ function LHNOptionsList({ LHNOptionsList.displayName = 'LHNOptionsList'; -export default withOnyx({ - reports: { - key: ONYXKEYS.COLLECTION.REPORT, - }, - reportActions: { - key: ONYXKEYS.COLLECTION.REPORT_ACTIONS, - }, - policy: { - key: ONYXKEYS.COLLECTION.POLICY, - }, - preferredLocale: { - key: ONYXKEYS.NVP_PREFERRED_LOCALE, - }, - personalDetails: { - key: ONYXKEYS.PERSONAL_DETAILS_LIST, - }, - transactions: { - key: ONYXKEYS.COLLECTION.TRANSACTION, - }, - draftComments: { - key: ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT, - }, - transactionViolations: { - key: ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, - }, -})(memo(LHNOptionsList)); +export default withCurrentReportID( + withOnyx({ + reports: { + key: ONYXKEYS.COLLECTION.REPORT, + }, + reportActions: { + key: ONYXKEYS.COLLECTION.REPORT_ACTIONS, + }, + policy: { + key: ONYXKEYS.COLLECTION.POLICY, + }, + preferredLocale: { + key: ONYXKEYS.NVP_PREFERRED_LOCALE, + }, + personalDetails: { + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + }, + transactions: { + key: ONYXKEYS.COLLECTION.TRANSACTION, + }, + draftComments: { + key: ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT, + }, + transactionViolations: { + key: ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, + }, + })(memo(LHNOptionsList)), +); export type {LHNOptionsListProps}; diff --git a/src/components/LHNOptionsList/OptionRowLHNData.tsx b/src/components/LHNOptionsList/OptionRowLHNData.tsx index 9b22b50b64fe..a3394190d0c1 100644 --- a/src/components/LHNOptionsList/OptionRowLHNData.tsx +++ b/src/components/LHNOptionsList/OptionRowLHNData.tsx @@ -1,6 +1,5 @@ import {deepEqual} from 'fast-equals'; import React, {useEffect, useMemo, useRef} from 'react'; -import useCurrentReportID from '@hooks/useCurrentReportID'; import * as ReportUtils from '@libs/ReportUtils'; import SidebarUtils from '@libs/SidebarUtils'; import * as Report from '@userActions/Report'; @@ -33,8 +32,6 @@ function OptionRowLHNData({ ...propsToForward }: OptionRowLHNDataProps) { const reportID = propsToForward.reportID; - const currentReportIDValue = useCurrentReportID(); - const isReportFocused = isFocused && currentReportIDValue?.currentReportID === reportID; const optionItemRef = useRef(); @@ -88,7 +85,7 @@ function OptionRowLHNData({ ); diff --git a/src/components/LHNOptionsList/types.ts b/src/components/LHNOptionsList/types.ts index 4ca30358f9b1..c122ab018392 100644 --- a/src/components/LHNOptionsList/types.ts +++ b/src/components/LHNOptionsList/types.ts @@ -3,6 +3,7 @@ import type {RefObject} from 'react'; import type {LayoutChangeEvent, StyleProp, TextStyle, View, ViewStyle} from 'react-native'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; +import type {CurrentReportIDContextValue} from '@components/withCurrentReportID'; import type CONST from '@src/CONST'; import type {OptionData} from '@src/libs/ReportUtils'; import type {Locale, PersonalDetailsList, Policy, Report, ReportAction, ReportActions, Transaction, TransactionViolation} from '@src/types/onyx'; @@ -63,7 +64,7 @@ type CustomLHNOptionsListProps = { reportIDsWithErrors: Record; }; -type LHNOptionsListProps = CustomLHNOptionsListProps & LHNOptionsListOnyxProps; +type LHNOptionsListProps = CustomLHNOptionsListProps & CurrentReportIDContextValue & LHNOptionsListOnyxProps; type OptionRowLHNDataProps = { /** Whether row should be focused */ diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 93ff73bcfaf2..e0d6c39623ed 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -20,6 +20,7 @@ import ConfirmModal from './ConfirmModal'; import HeaderWithBackButton from './HeaderWithBackButton'; import * as Expensicons from './Icon/Expensicons'; import MoneyReportHeaderStatusBar from './MoneyReportHeaderStatusBar'; +import {usePersonalDetails} from './OnyxProvider'; import SettlementButton from './SettlementButton'; type PaymentType = DeepValueOf; @@ -44,6 +45,7 @@ type MoneyReportHeaderProps = MoneyReportHeaderOnyxProps & { }; function MoneyReportHeader({session, policy, chatReport, nextStep, report: moneyRequestReport}: MoneyReportHeaderProps) { + const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; const styles = useThemeStyles(); const {translate} = useLocalize(); const {windowWidth, isSmallScreenWidth} = useWindowDimensions(); @@ -100,6 +102,7 @@ function MoneyReportHeader({session, policy, chatReport, nextStep, report: money shouldShowPinButton={false} report={moneyRequestReport} policy={policy} + personalDetails={personalDetails} shouldShowBackButton={isSmallScreenWidth} onBackButtonPress={() => Navigation.goBack(undefined, false, true)} // Shows border if no buttons or next steps are showing below the header diff --git a/src/components/MoneyRequestHeader.tsx b/src/components/MoneyRequestHeader.tsx index 3dd06b67b637..b5c84354e466 100644 --- a/src/components/MoneyRequestHeader.tsx +++ b/src/components/MoneyRequestHeader.tsx @@ -21,6 +21,7 @@ import HeaderWithBackButton from './HeaderWithBackButton'; import HoldBanner from './HoldBanner'; import * as Expensicons from './Icon/Expensicons'; import MoneyRequestHeaderStatusBar from './MoneyRequestHeaderStatusBar'; +import {usePersonalDetails} from './OnyxProvider'; import ProcessMoneyRequestHoldMenu from './ProcessMoneyRequestHoldMenu'; type MoneyRequestHeaderOnyxProps = { @@ -53,6 +54,7 @@ type MoneyRequestHeaderProps = MoneyRequestHeaderOnyxProps & { }; function MoneyRequestHeader({session, parentReport, report, parentReportAction, transaction, shownHoldUseExplanation = false, policy}: MoneyRequestHeaderProps) { + const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; const styles = useThemeStyles(); const {translate} = useLocalize(); const [isDeleteModalVisible, setIsDeleteModalVisible] = useState(false); @@ -171,6 +173,7 @@ function MoneyRequestHeader({session, parentReport, report, parentReportAction, ownerAccountID: parentReport?.ownerAccountID, }} policy={policy} + personalDetails={personalDetails} shouldShowBackButton={isSmallScreenWidth} onBackButtonPress={() => Navigation.goBack(undefined, false, true)} /> diff --git a/src/libs/Pusher/pusher.ts b/src/libs/Pusher/pusher.ts index 48c5e5c1409f..3cb15c0f3fc3 100644 --- a/src/libs/Pusher/pusher.ts +++ b/src/libs/Pusher/pusher.ts @@ -1,6 +1,5 @@ import isObject from 'lodash/isObject'; import type {Channel, ChannelAuthorizerGenerator, Options} from 'pusher-js/with-encryption'; -import {InteractionManager} from 'react-native'; import Onyx from 'react-native-onyx'; import type {LiteralUnion, ValueOf} from 'type-fest'; import Log from '@libs/Log'; @@ -227,50 +226,48 @@ function subscribe( onResubscribe = () => {}, ): Promise { return new Promise((resolve, reject) => { - InteractionManager.runAfterInteractions(() => { - // We cannot call subscribe() before init(). Prevent any attempt to do this on dev. - if (!socket) { - throw new Error(`[Pusher] instance not found. Pusher.subscribe() + // We cannot call subscribe() before init(). Prevent any attempt to do this on dev. + if (!socket) { + throw new Error(`[Pusher] instance not found. Pusher.subscribe() most likely has been called before Pusher.init()`); - } - - Log.info('[Pusher] Attempting to subscribe to channel', false, {channelName, eventName}); - let channel = getChannel(channelName); - - if (!channel || !channel.subscribed) { - channel = socket.subscribe(channelName); - let isBound = false; - channel.bind('pusher:subscription_succeeded', () => { - // Check so that we do not bind another event with each reconnect attempt - if (!isBound) { - bindEventToChannel(channel, eventName, eventCallback); - resolve(); - isBound = true; - return; - } - - // When subscribing for the first time we register a success callback that can be - // called multiple times when the subscription succeeds again in the future - // e.g. as a result of Pusher disconnecting and reconnecting. This callback does - // not fire on the first subscription_succeeded event. - onResubscribe(); - }); + } - channel.bind('pusher:subscription_error', (data: PusherSubscribtionErrorData = {}) => { - const {type, error, status} = data; - Log.hmmm('[Pusher] Issue authenticating with Pusher during subscribe attempt.', { - channelName, - status, - type, - error, - }); - reject(error); + Log.info('[Pusher] Attempting to subscribe to channel', false, {channelName, eventName}); + let channel = getChannel(channelName); + + if (!channel || !channel.subscribed) { + channel = socket.subscribe(channelName); + let isBound = false; + channel.bind('pusher:subscription_succeeded', () => { + // Check so that we do not bind another event with each reconnect attempt + if (!isBound) { + bindEventToChannel(channel, eventName, eventCallback); + resolve(); + isBound = true; + return; + } + + // When subscribing for the first time we register a success callback that can be + // called multiple times when the subscription succeeds again in the future + // e.g. as a result of Pusher disconnecting and reconnecting. This callback does + // not fire on the first subscription_succeeded event. + onResubscribe(); + }); + + channel.bind('pusher:subscription_error', (data: PusherSubscribtionErrorData = {}) => { + const {type, error, status} = data; + Log.hmmm('[Pusher] Issue authenticating with Pusher during subscribe attempt.', { + channelName, + status, + type, + error, }); - } else { - bindEventToChannel(channel, eventName, eventCallback); - resolve(); - } - }); + reject(error); + }); + } else { + bindEventToChannel(channel, eventName, eventCallback); + resolve(); + } }); } diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 749c22c41c42..b677b5369b68 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -2903,17 +2903,6 @@ function clearNewRoomFormError() { }); } -function getReportDraftStatus(reportID: string) { - if (!allReports) { - return false; - } - - if (!allReports[reportID]) { - return false; - } - return allReports[reportID]?.hasDraft; -} - function resolveActionableMentionWhisper(reportId: string, reportAction: OnyxEntry, resolution: ValueOf) { const message = reportAction?.message?.[0]; if (!message) { @@ -2964,7 +2953,6 @@ function resolveActionableMentionWhisper(reportId: string, reportAction: OnyxEnt } export { - getReportDraftStatus, searchInServer, addComment, addAttachment, diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index f9f73be2ab45..c452d5be2aaf 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -2,8 +2,7 @@ import {useIsFocused} from '@react-navigation/native'; import type {StackScreenProps} from '@react-navigation/stack'; import lodashIsEqual from 'lodash/isEqual'; import React, {memo, useCallback, useEffect, useMemo, useRef, useState} from 'react'; -import {InteractionManager, View} from 'react-native'; -import type {FlatList, ViewStyle} from 'react-native'; +import type {FlatList, View, ViewStyle} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import type {WithOnyxInstanceState} from 'react-native-onyx/dist/types'; @@ -348,11 +347,8 @@ function ReportScreen({ Performance.markEnd(CONST.TIMING.CHAT_RENDER); fetchReportIfNeeded(); - const interactionTask = InteractionManager.runAfterInteractions(() => { - ComposerActions.setShouldShowComposeInput(true); - }); + ComposerActions.setShouldShowComposeInput(true); return () => { - interactionTask?.cancel(); if (!didSubscribeToReportLeavingEvents) { return; } @@ -426,20 +422,10 @@ function ReportScreen({ // any `pendingFields.createChat` or `pendingFields.addWorkspaceRoom` fields are set to null. // Existing reports created will have empty fields for `pendingFields`. const didCreateReportSuccessfully = !report.pendingFields || (!report.pendingFields.addWorkspaceRoom && !report.pendingFields.createChat); - let interactionTask: ReturnType | undefined; if (!didSubscribeToReportLeavingEvents.current && didCreateReportSuccessfully) { - interactionTask = InteractionManager.runAfterInteractions(() => { - Report.subscribeToReportLeavingEvents(reportID); - didSubscribeToReportLeavingEvents.current = true; - }); + Report.subscribeToReportLeavingEvents(reportID); + didSubscribeToReportLeavingEvents.current = true; } - - return () => { - if (!interactionTask) { - return; - } - interactionTask.cancel(); - }; }, [report, didSubscribeToReportLeavingEvents, reportID]); const onListLayout = useCallback((event: LayoutChangeEvent) => { @@ -530,8 +516,8 @@ function ReportScreen({ )} {/* Note: The ReportActionsSkeletonView should be allowed to mount even if the initial report actions are not loaded. - If we prevent rendering the report while they are loading then - we'll unnecessarily unmount the ReportActionsView which will clear the new marker lines initial state. */} + If we prevent rendering the report while they are loading then + we'll unnecessarily unmount the ReportActionsView which will clear the new marker lines initial state. */} {(!isReportReadyForDisplay || isLoadingInitialReportActions || isLoading) && } {isReportReadyForDisplay ? ( @@ -543,7 +529,9 @@ function ReportScreen({ isEmptyChat={isEmptyChat} lastReportAction={lastReportAction} /> - ) : null} + ) : ( + + )} diff --git a/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.tsx b/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.tsx index ee408b2d1545..6bbe5b10802f 100644 --- a/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.tsx +++ b/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.tsx @@ -419,23 +419,15 @@ function ComposerWithSuggestions( Report.setReportWithDraft(reportID, true); } - const hasDraftStatus = Report.getReportDraftStatus(reportID); - - /** - * The extra `!hasDraftStatus` check is to prevent the draft being set - * when the user navigates to the ReportScreen. This doesn't alter anything - * in terms of functionality. - */ // The draft has been deleted. - if (newCommentConverted.length === 0 && hasDraftStatus) { + if (newCommentConverted.length === 0) { Report.setReportWithDraft(reportID, false); } commentRef.current = newCommentConverted; - const isDraftCommentEmpty = getDraftComment(reportID) === ''; if (shouldDebounceSaveComment) { debouncedSaveReportComment(reportID, newCommentConverted); - } else if (isDraftCommentEmpty && newCommentConverted.length !== 0) { + } else { Report.saveReportComment(reportID, newCommentConverted || ''); } if (newCommentConverted) { @@ -684,6 +676,13 @@ function ComposerWithSuggestions( useEffect(() => { // Scrolls the composer to the bottom and sets the selection to the end, so that longer drafts are easier to edit updateMultilineInputRange(textInputRef.current, !!shouldAutoFocus); + + if (value.length === 0) { + return; + } + + Report.setReportWithDraft(reportID, true); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useImperativeHandle( diff --git a/src/pages/home/report/ReportActionCompose/SilentCommentUpdater/index.tsx b/src/pages/home/report/ReportActionCompose/SilentCommentUpdater/index.tsx index f3780528cabe..1abc6567bc7b 100644 --- a/src/pages/home/report/ReportActionCompose/SilentCommentUpdater/index.tsx +++ b/src/pages/home/report/ReportActionCompose/SilentCommentUpdater/index.tsx @@ -17,17 +17,7 @@ function SilentCommentUpdater({comment, commentRef, reportID, value, updateComme const prevPreferredLocale = usePrevious(preferredLocale); useEffect(() => { - /** - * Schedules the callback to run when the main thread is idle. - */ - if ('requestIdleCallback' in window) { - const callbackID = requestIdleCallback(() => { - updateComment(comment ?? ''); - }); - return () => cancelIdleCallback(callbackID); - } updateComment(comment ?? ''); - // eslint-disable-next-line react-hooks/exhaustive-deps -- We need to run this on mount }, []); diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index 6b7175396e6c..748a30d75805 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -108,8 +108,6 @@ function isMessageUnread(message: OnyxTypes.ReportAction, lastReadTime?: string) return !!(message && lastReadTime && message.created && lastReadTime < message.created); } -const onScrollToIndexFailed = () => {}; - function ReportActionsList({ report, parentReportAction, @@ -298,9 +296,7 @@ function ReportActionsList({ if (unsubscribe) { unsubscribe(); } - InteractionManager.runAfterInteractions(() => { - Report.unsubscribeFromReportChannel(report.reportID); - }); + Report.unsubscribeFromReportChannel(report.reportID); }; newActionUnsubscribeMap[report.reportID] = cleanup; @@ -477,7 +473,7 @@ function ReportActionsList({ // Native mobile does not render updates flatlist the changes even though component did update called. // To notify there something changes we can use extraData prop to flatlist - const extraData = useMemo(() => [isSmallScreenWidth ? currentUnreadMarker : undefined, ReportUtils.isArchivedRoom(report)], [currentUnreadMarker, isSmallScreenWidth, report]); + const extraData = [isSmallScreenWidth ? currentUnreadMarker : undefined, ReportUtils.isArchivedRoom(report)]; const hideComposer = !ReportUtils.canUserPerformWriteAction(report); const shouldShowReportRecipientLocalTime = ReportUtils.canShowReportRecipientLocalTime(personalDetailsList, report, currentUserPersonalDetails.accountID) && !isComposerFullSize; @@ -554,7 +550,7 @@ function ReportActionsList({ keyboardShouldPersistTaps="handled" onLayout={onLayoutInner} onScroll={trackVerticalScrolling} - onScrollToIndexFailed={onScrollToIndexFailed} + onScrollToIndexFailed={() => {}} extraData={extraData} /> diff --git a/src/pages/home/report/ReportActionsView.tsx b/src/pages/home/report/ReportActionsView.tsx index e8401289fc85..ab3bda2fa8ca 100755 --- a/src/pages/home/report/ReportActionsView.tsx +++ b/src/pages/home/report/ReportActionsView.tsx @@ -2,7 +2,6 @@ import {useIsFocused} from '@react-navigation/native'; import lodashIsEqual from 'lodash/isEqual'; import lodashThrottle from 'lodash/throttle'; import React, {useCallback, useContext, useEffect, useMemo, useRef} from 'react'; -import {InteractionManager} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; import useCopySelectionHelper from '@hooks/useCopySelectionHelper'; @@ -91,12 +90,7 @@ function ReportActionsView({ }; useEffect(() => { - const interactionTask = InteractionManager.runAfterInteractions(() => { - openReportIfNecessary(); - }); - return () => { - interactionTask?.cancel(); - }; + openReportIfNecessary(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); @@ -150,20 +144,10 @@ function ReportActionsView({ // any `pendingFields.createChat` or `pendingFields.addWorkspaceRoom` fields are set to null. // Existing reports created will have empty fields for `pendingFields`. const didCreateReportSuccessfully = !report.pendingFields || (!report.pendingFields.addWorkspaceRoom && !report.pendingFields.createChat); - let interactionTask: ReturnType | undefined; if (!didSubscribeToReportTypingEvents.current && didCreateReportSuccessfully) { - interactionTask = InteractionManager.runAfterInteractions(() => { - Report.subscribeToReportTypingEvents(reportID); - didSubscribeToReportTypingEvents.current = true; - }); + Report.subscribeToReportTypingEvents(reportID); + didSubscribeToReportTypingEvents.current = true; } - - return () => { - if (!interactionTask) { - return; - } - interactionTask.cancel(); - }; }, [report.pendingFields, didSubscribeToReportTypingEvents, reportID]); const oldestReportAction = useMemo(() => reportActions?.at(-1), [reportActions]); diff --git a/src/pages/home/sidebar/SidebarLinks.js b/src/pages/home/sidebar/SidebarLinks.js index dc5d5d4d07dd..0a97f00c5002 100644 --- a/src/pages/home/sidebar/SidebarLinks.js +++ b/src/pages/home/sidebar/SidebarLinks.js @@ -1,7 +1,7 @@ /* eslint-disable rulesdir/onyx-props-must-have-default */ import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; -import React, {memo, useCallback, useEffect, useMemo, useRef} from 'react'; +import React, {useCallback, useEffect, useMemo, useRef} from 'react'; import {InteractionManager, StyleSheet, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; @@ -173,5 +173,5 @@ export default withOnyx({ activePolicy: { key: ({activeWorkspaceID}) => `${ONYXKEYS.COLLECTION.POLICY}${activeWorkspaceID}`, }, -})(memo(SidebarLinks)); +})(SidebarLinks); export {basePropTypes}; From 7d9c6a2250a2e0687b603dacb369a9e692bcd7ce Mon Sep 17 00:00:00 2001 From: Vit Horacek Date: Mon, 11 Mar 2024 18:22:30 +0000 Subject: [PATCH 2/3] Fix style --- package-lock.json | 147 -------------------------------- src/pages/home/ReportScreen.tsx | 3 +- 2 files changed, 2 insertions(+), 148 deletions(-) diff --git a/package-lock.json b/package-lock.json index 67e939b8bf44..9cb7f5c08b08 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8046,153 +8046,6 @@ "integrity": "sha512-C9Br1BQqm6io6lvYHptlLcOHbzlaqxp9tS35P8Qj3pdiiYRTzU3KPvZ61rQ+ZnZ4FOQ6MwPsKsmB8+6WHkAY6Q==", "license": "MIT" }, - "node_modules/@onfido/active-video-capture": { - "version": "0.28.6", - "resolved": "https://registry.npmjs.org/@onfido/active-video-capture/-/active-video-capture-0.28.6.tgz", - "integrity": "sha512-RFUeKaOSjj/amPp6VzhVkq/7kIkutEnnttT9n5KDeD3Vx8a09KD3a/xvxdQppveHlDAYsdBP6LrJwSSpjXiprg==", - "dependencies": { - "@mediapipe/face_detection": "^0.4.1646425229", - "@mediapipe/face_mesh": "^0.4.1633559619", - "@onfido/castor": "^2.2.2", - "@onfido/castor-icons": "^2.12.0", - "@tensorflow-models/face-detection": "^1.0.1", - "@tensorflow-models/face-landmarks-detection": "^1.0.2", - "@tensorflow/tfjs-backend-wasm": "3.20.0", - "@tensorflow/tfjs-backend-webgl": "3.20.0", - "@tensorflow/tfjs-converter": "3.20.0", - "@tensorflow/tfjs-core": "3.20.0", - "preact": "10.11.3", - "react-webcam": "^7.2.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@onfido/active-video-capture/node_modules/@tensorflow-models/face-landmarks-detection": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@tensorflow-models/face-landmarks-detection/-/face-landmarks-detection-1.0.5.tgz", - "integrity": "sha512-54XJPi8g29/MknJ33ZBrLsEzr9kw/dJtrJMMD3xrCrnRlfFQPIKQ5PI2Wml55Fz2p4U2hemzBB0/H+S94JddIQ==", - "dependencies": { - "rimraf": "^3.0.2" - }, - "peerDependencies": { - "@mediapipe/face_mesh": "~0.4.0", - "@tensorflow-models/face-detection": "~1.0.0", - "@tensorflow/tfjs-backend-webgl": "^3.12.0", - "@tensorflow/tfjs-converter": "^3.12.0", - "@tensorflow/tfjs-core": "^3.12.0" - } - }, - "node_modules/@onfido/active-video-capture/node_modules/@tensorflow/tfjs-backend-cpu": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-3.20.0.tgz", - "integrity": "sha512-gf075YaBLwSAAiUwa0D4GvYyUBhbJ1BVSivUNQmUfGKvIr2lIhF0qstBr033YTc3lhkbFSHEEPAHh/EfpqyjXQ==", - "dependencies": { - "@types/seedrandom": "^2.4.28", - "seedrandom": "^3.0.5" - }, - "engines": { - "yarn": ">= 1.3.2" - }, - "peerDependencies": { - "@tensorflow/tfjs-core": "3.20.0" - } - }, - "node_modules/@onfido/active-video-capture/node_modules/@tensorflow/tfjs-backend-wasm": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-wasm/-/tfjs-backend-wasm-3.20.0.tgz", - "integrity": "sha512-k+sDcrcPtGToLjKRffgtSqlcN4MC6g4hXWRarZfgvvyvFqpxVfVqrGYHGTirXdN47sKYhmcTSMvbM2quGaaQnA==", - "dependencies": { - "@tensorflow/tfjs-backend-cpu": "3.20.0", - "@types/emscripten": "~0.0.34" - }, - "peerDependencies": { - "@tensorflow/tfjs-core": "3.20.0" - } - }, - "node_modules/@onfido/active-video-capture/node_modules/@tensorflow/tfjs-backend-webgl": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-3.20.0.tgz", - "integrity": "sha512-SucbyQ08re3HvRgVfarRtKFIjNM4JvIAzcXmw4vaE/HrCtPEePkGO1VrmfQoN470EdUmGiwgqAjoyBvM2VOlVg==", - "dependencies": { - "@tensorflow/tfjs-backend-cpu": "3.20.0", - "@types/offscreencanvas": "~2019.3.0", - "@types/seedrandom": "^2.4.28", - "@types/webgl-ext": "0.0.30", - "@types/webgl2": "0.0.6", - "seedrandom": "^3.0.5" - }, - "engines": { - "yarn": ">= 1.3.2" - }, - "peerDependencies": { - "@tensorflow/tfjs-core": "3.20.0" - } - }, - "node_modules/@onfido/active-video-capture/node_modules/@tensorflow/tfjs-converter": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-3.20.0.tgz", - "integrity": "sha512-8EIYqtQwvSYw9GFNW2OFU8Qnl/FQF/kKAsQJoORYaZ419WJo+FIZWbAWDtCpJSAgkgoHH1jYWgV9H313cVmqxg==", - "peerDependencies": { - "@tensorflow/tfjs-core": "3.20.0" - } - }, - "node_modules/@onfido/active-video-capture/node_modules/@tensorflow/tfjs-core": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-3.20.0.tgz", - "integrity": "sha512-L16JyVA4a8jFJXFgB9/oYZxcGq/GfLypt5dMVTyedznARZZ9SiY/UMMbo3IKl9ZylG1dOVVTpjzV3EvBYfeJXw==", - "dependencies": { - "@types/long": "^4.0.1", - "@types/offscreencanvas": "~2019.3.0", - "@types/seedrandom": "^2.4.28", - "@types/webgl-ext": "0.0.30", - "@webgpu/types": "0.1.16", - "long": "4.0.0", - "node-fetch": "~2.6.1", - "seedrandom": "^3.0.5" - }, - "engines": { - "yarn": ">= 1.3.2" - } - }, - "node_modules/@onfido/active-video-capture/node_modules/@webgpu/types": { - "version": "0.1.16", - "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.16.tgz", - "integrity": "sha512-9E61voMP4+Rze02jlTXud++Htpjyyk8vw5Hyw9FGRrmhHQg2GqbuOfwf5Klrb8vTxc2XWI3EfO7RUHMpxTj26A==" - }, - "node_modules/@onfido/castor": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@onfido/castor/-/castor-2.3.0.tgz", - "integrity": "sha512-FkydkjedS6b2g3SqgZMYnVRZvUs/MkaEuXXJWG9+LNc7DMFT1K8smOnNuHzkiM3cJhXL6yAADdKE0mg+ZIrucQ==", - "dependencies": { - "@onfido/castor-tokens": "^1.0.0-beta.6", - "csstype": "^3.1.1" - }, - "peerDependencies": { - "@onfido/castor-icons": ">=1.0.0" - } - }, - "node_modules/@onfido/castor-icons": { - "version": "2.22.0", - "resolved": "https://registry.npmjs.org/@onfido/castor-icons/-/castor-icons-2.22.0.tgz", - "integrity": "sha512-7OnCvu5xqVWcBLqovZyb99NP0oHw7sjkVYXZhi438i0U6Pgecrhu/14Gc/IN/kvgDxWj9qmiYdd0qdjNaVckrQ==", - "peerDependencies": { - "react": ">=17 || ^16.14 || ^15.7 || ^0.14.10" - } - }, - "node_modules/@onfido/castor-tokens": { - "version": "1.0.0-beta.6", - "resolved": "https://registry.npmjs.org/@onfido/castor-tokens/-/castor-tokens-1.0.0-beta.6.tgz", - "integrity": "sha512-MfwuSlNdM0Ay0cI3LLyqZGsHW0e1Y1R/0IdQKVU575PdWQx1Q/538aOZMo/a3/oSW0pMEgfOm+mNqPx057cvWA==" - }, - "node_modules/@onfido/opencv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@onfido/opencv/-/opencv-2.1.1.tgz", - "integrity": "sha512-Bwo0YsZrrdm+p5hpNFZ7yrqNVWJxOUbQW9aWDEUtkDWUL+nX2RHIR6F4lBGVmbqnG24anadS/+nEvy80SwD3tQ==", - "dependencies": { - "mirada": "^0.0.15" - } - }, "node_modules/@onfido/react-native-sdk": { "version": "10.6.0", "resolved": "https://registry.npmjs.org/@onfido/react-native-sdk/-/react-native-sdk-10.6.0.tgz", diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index c452d5be2aaf..d4221c324ade 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -2,7 +2,8 @@ import {useIsFocused} from '@react-navigation/native'; import type {StackScreenProps} from '@react-navigation/stack'; import lodashIsEqual from 'lodash/isEqual'; import React, {memo, useCallback, useEffect, useMemo, useRef, useState} from 'react'; -import type {FlatList, View, ViewStyle} from 'react-native'; +import {View} from 'react-native'; +import type {FlatList, ViewStyle} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import type {WithOnyxInstanceState} from 'react-native-onyx/dist/types'; From 565844e9c055f93953025ac0814c713107536cfd Mon Sep 17 00:00:00 2001 From: Vit Horacek Date: Mon, 11 Mar 2024 18:25:53 +0000 Subject: [PATCH 3/3] Resolve unnecessary change --- package-lock.json | 147 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) diff --git a/package-lock.json b/package-lock.json index 9cb7f5c08b08..67e939b8bf44 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8046,6 +8046,153 @@ "integrity": "sha512-C9Br1BQqm6io6lvYHptlLcOHbzlaqxp9tS35P8Qj3pdiiYRTzU3KPvZ61rQ+ZnZ4FOQ6MwPsKsmB8+6WHkAY6Q==", "license": "MIT" }, + "node_modules/@onfido/active-video-capture": { + "version": "0.28.6", + "resolved": "https://registry.npmjs.org/@onfido/active-video-capture/-/active-video-capture-0.28.6.tgz", + "integrity": "sha512-RFUeKaOSjj/amPp6VzhVkq/7kIkutEnnttT9n5KDeD3Vx8a09KD3a/xvxdQppveHlDAYsdBP6LrJwSSpjXiprg==", + "dependencies": { + "@mediapipe/face_detection": "^0.4.1646425229", + "@mediapipe/face_mesh": "^0.4.1633559619", + "@onfido/castor": "^2.2.2", + "@onfido/castor-icons": "^2.12.0", + "@tensorflow-models/face-detection": "^1.0.1", + "@tensorflow-models/face-landmarks-detection": "^1.0.2", + "@tensorflow/tfjs-backend-wasm": "3.20.0", + "@tensorflow/tfjs-backend-webgl": "3.20.0", + "@tensorflow/tfjs-converter": "3.20.0", + "@tensorflow/tfjs-core": "3.20.0", + "preact": "10.11.3", + "react-webcam": "^7.2.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@onfido/active-video-capture/node_modules/@tensorflow-models/face-landmarks-detection": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@tensorflow-models/face-landmarks-detection/-/face-landmarks-detection-1.0.5.tgz", + "integrity": "sha512-54XJPi8g29/MknJ33ZBrLsEzr9kw/dJtrJMMD3xrCrnRlfFQPIKQ5PI2Wml55Fz2p4U2hemzBB0/H+S94JddIQ==", + "dependencies": { + "rimraf": "^3.0.2" + }, + "peerDependencies": { + "@mediapipe/face_mesh": "~0.4.0", + "@tensorflow-models/face-detection": "~1.0.0", + "@tensorflow/tfjs-backend-webgl": "^3.12.0", + "@tensorflow/tfjs-converter": "^3.12.0", + "@tensorflow/tfjs-core": "^3.12.0" + } + }, + "node_modules/@onfido/active-video-capture/node_modules/@tensorflow/tfjs-backend-cpu": { + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-3.20.0.tgz", + "integrity": "sha512-gf075YaBLwSAAiUwa0D4GvYyUBhbJ1BVSivUNQmUfGKvIr2lIhF0qstBr033YTc3lhkbFSHEEPAHh/EfpqyjXQ==", + "dependencies": { + "@types/seedrandom": "^2.4.28", + "seedrandom": "^3.0.5" + }, + "engines": { + "yarn": ">= 1.3.2" + }, + "peerDependencies": { + "@tensorflow/tfjs-core": "3.20.0" + } + }, + "node_modules/@onfido/active-video-capture/node_modules/@tensorflow/tfjs-backend-wasm": { + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-wasm/-/tfjs-backend-wasm-3.20.0.tgz", + "integrity": "sha512-k+sDcrcPtGToLjKRffgtSqlcN4MC6g4hXWRarZfgvvyvFqpxVfVqrGYHGTirXdN47sKYhmcTSMvbM2quGaaQnA==", + "dependencies": { + "@tensorflow/tfjs-backend-cpu": "3.20.0", + "@types/emscripten": "~0.0.34" + }, + "peerDependencies": { + "@tensorflow/tfjs-core": "3.20.0" + } + }, + "node_modules/@onfido/active-video-capture/node_modules/@tensorflow/tfjs-backend-webgl": { + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-3.20.0.tgz", + "integrity": "sha512-SucbyQ08re3HvRgVfarRtKFIjNM4JvIAzcXmw4vaE/HrCtPEePkGO1VrmfQoN470EdUmGiwgqAjoyBvM2VOlVg==", + "dependencies": { + "@tensorflow/tfjs-backend-cpu": "3.20.0", + "@types/offscreencanvas": "~2019.3.0", + "@types/seedrandom": "^2.4.28", + "@types/webgl-ext": "0.0.30", + "@types/webgl2": "0.0.6", + "seedrandom": "^3.0.5" + }, + "engines": { + "yarn": ">= 1.3.2" + }, + "peerDependencies": { + "@tensorflow/tfjs-core": "3.20.0" + } + }, + "node_modules/@onfido/active-video-capture/node_modules/@tensorflow/tfjs-converter": { + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-3.20.0.tgz", + "integrity": "sha512-8EIYqtQwvSYw9GFNW2OFU8Qnl/FQF/kKAsQJoORYaZ419WJo+FIZWbAWDtCpJSAgkgoHH1jYWgV9H313cVmqxg==", + "peerDependencies": { + "@tensorflow/tfjs-core": "3.20.0" + } + }, + "node_modules/@onfido/active-video-capture/node_modules/@tensorflow/tfjs-core": { + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-3.20.0.tgz", + "integrity": "sha512-L16JyVA4a8jFJXFgB9/oYZxcGq/GfLypt5dMVTyedznARZZ9SiY/UMMbo3IKl9ZylG1dOVVTpjzV3EvBYfeJXw==", + "dependencies": { + "@types/long": "^4.0.1", + "@types/offscreencanvas": "~2019.3.0", + "@types/seedrandom": "^2.4.28", + "@types/webgl-ext": "0.0.30", + "@webgpu/types": "0.1.16", + "long": "4.0.0", + "node-fetch": "~2.6.1", + "seedrandom": "^3.0.5" + }, + "engines": { + "yarn": ">= 1.3.2" + } + }, + "node_modules/@onfido/active-video-capture/node_modules/@webgpu/types": { + "version": "0.1.16", + "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.16.tgz", + "integrity": "sha512-9E61voMP4+Rze02jlTXud++Htpjyyk8vw5Hyw9FGRrmhHQg2GqbuOfwf5Klrb8vTxc2XWI3EfO7RUHMpxTj26A==" + }, + "node_modules/@onfido/castor": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@onfido/castor/-/castor-2.3.0.tgz", + "integrity": "sha512-FkydkjedS6b2g3SqgZMYnVRZvUs/MkaEuXXJWG9+LNc7DMFT1K8smOnNuHzkiM3cJhXL6yAADdKE0mg+ZIrucQ==", + "dependencies": { + "@onfido/castor-tokens": "^1.0.0-beta.6", + "csstype": "^3.1.1" + }, + "peerDependencies": { + "@onfido/castor-icons": ">=1.0.0" + } + }, + "node_modules/@onfido/castor-icons": { + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/@onfido/castor-icons/-/castor-icons-2.22.0.tgz", + "integrity": "sha512-7OnCvu5xqVWcBLqovZyb99NP0oHw7sjkVYXZhi438i0U6Pgecrhu/14Gc/IN/kvgDxWj9qmiYdd0qdjNaVckrQ==", + "peerDependencies": { + "react": ">=17 || ^16.14 || ^15.7 || ^0.14.10" + } + }, + "node_modules/@onfido/castor-tokens": { + "version": "1.0.0-beta.6", + "resolved": "https://registry.npmjs.org/@onfido/castor-tokens/-/castor-tokens-1.0.0-beta.6.tgz", + "integrity": "sha512-MfwuSlNdM0Ay0cI3LLyqZGsHW0e1Y1R/0IdQKVU575PdWQx1Q/538aOZMo/a3/oSW0pMEgfOm+mNqPx057cvWA==" + }, + "node_modules/@onfido/opencv": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@onfido/opencv/-/opencv-2.1.1.tgz", + "integrity": "sha512-Bwo0YsZrrdm+p5hpNFZ7yrqNVWJxOUbQW9aWDEUtkDWUL+nX2RHIR6F4lBGVmbqnG24anadS/+nEvy80SwD3tQ==", + "dependencies": { + "mirada": "^0.0.15" + } + }, "node_modules/@onfido/react-native-sdk": { "version": "10.6.0", "resolved": "https://registry.npmjs.org/@onfido/react-native-sdk/-/react-native-sdk-10.6.0.tgz",