From 46a6c3e52188ce55edad92a107ecbe4b930f825d Mon Sep 17 00:00:00 2001 From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com> Date: Sun, 21 Apr 2024 18:07:24 +0530 Subject: [PATCH 001/207] Show console debug logs via test tools menu --- ios/Podfile | 17 ++ src/CONST.ts | 3 +- src/ROUTES.ts | 2 +- .../BaseClientSideLoggingToolMenu.tsx | 21 +- .../ConsoleComponents.tsx | 191 ++++++++++++++++++ .../ConsoleModal.tsx | 64 ++++++ .../index.android.tsx | 4 +- .../ClientSideLoggingToolMenu/index.ios.tsx | 4 +- .../ClientSideLoggingToolMenu/index.tsx | 4 +- src/components/Modal/index.tsx | 2 +- src/components/TestToolsModal.tsx | 2 +- src/libs/Navigation/types.ts | 1 + src/pages/settings/AboutPage/ConsolePage.tsx | 158 +-------------- .../ShareLogList/BaseShareLogList.tsx | 10 +- .../AboutPage/ShareLogList/index.native.tsx | 4 +- .../settings/AboutPage/ShareLogList/index.tsx | 4 +- src/pages/settings/AboutPage/ShareLogPage.tsx | 2 +- .../utils/generators/ModalStyleUtils.ts | 23 +++ 18 files changed, 345 insertions(+), 171 deletions(-) create mode 100644 src/components/ClientSideLoggingToolMenu/ConsoleComponents.tsx create mode 100644 src/components/ClientSideLoggingToolMenu/ConsoleModal.tsx diff --git a/ios/Podfile b/ios/Podfile index 4f00eb2adfdd..0c524878e5f7 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,3 +1,5 @@ +use_frameworks! :linkage => :static + require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking") # Set the type of Mapbox SDK to use # This value is used by $RNMapboxMaps @@ -111,6 +113,21 @@ target 'NewExpensify' do end end end + + deployment_target = '13.4' + + installer.generated_projects.each do |project| + project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = deployment_target + end + end + project.build_configurations.each do |config| + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = deployment_target + end + end + + `sed -i -e $'s/__IPHONE_10_0/__IPHONE_15_0/' #{installer.sandbox.root}/RCT-Folly/folly/portability/Time.h` end end diff --git a/src/CONST.ts b/src/CONST.ts index 2cd614b74816..4ded9e282d3e 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -860,6 +860,7 @@ const CONST = { POPOVER: 'popover', RIGHT_DOCKED: 'right_docked', ONBOARDING: 'onboarding', + CENTERED_SMALL_AND_UNSWIPEABLE: 'centered_small_and_unswipeable' }, ANCHOR_ORIGIN_VERTICAL: { TOP: 'top', @@ -3100,7 +3101,7 @@ const CONST = { // Test tool menu parameters TEST_TOOL: { // Number of concurrent taps to open then the Test modal menu - NUMBER_OF_TAPS: 4, + NUMBER_OF_TAPS: 2, }, MENU_HELP_URLS: { diff --git a/src/ROUTES.ts b/src/ROUTES.ts index ceb4c217cb6e..71e673aea994 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -175,7 +175,7 @@ const ROUTES = { SETTINGS_CONSOLE: 'settings/troubleshoot/console', SETTINGS_SHARE_LOG: { route: 'settings/troubleshoot/console/share-log', - getRoute: (source: string) => `settings/troubleshoot/console/share-log?source=${encodeURI(source)}` as const, + getRoute: (source: string, isViaTestToolsModal = false) => `settings/troubleshoot/console/share-log?source=${encodeURI(source)}&isViaTestToolsModal=${isViaTestToolsModal}` as const, }, SETTINGS_EXIT_SURVEY_REASON: 'settings/exit-survey/reason', diff --git a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx index fcad770908a6..a6bb085c949a 100644 --- a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx +++ b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, {useState} from 'react'; import {Alert} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; @@ -12,6 +12,7 @@ import * as Console from '@libs/actions/Console'; import {parseStringifiedMessages} from '@libs/Console'; import ONYXKEYS from '@src/ONYXKEYS'; import type {CapturedLogs, Log} from '@src/types/onyx'; +import ConsoleModal from "@components/ClientSideLoggingToolMenu/ConsoleModal"; type BaseClientSideLoggingToolMenuOnyxProps = { /** Logs captured on the current device */ @@ -30,9 +31,11 @@ type BaseClientSideLoggingToolProps = { onDisableLogging: (logs: Log[]) => void; /** Action to run when enabling logging */ onEnableLogging?: () => void; + /** Boolean to know if this was opened via test tools modal */ + isViaTestToolsModal: boolean } & BaseClientSideLoggingToolMenuOnyxProps; -function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onShareLogs, onDisableLogging, onEnableLogging}: BaseClientSideLoggingToolProps) { +function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onShareLogs, onDisableLogging, onEnableLogging, isViaTestToolsModal, closeTestToolsModal}: BaseClientSideLoggingToolProps) { const {translate} = useLocalize(); const onToggle = () => { @@ -59,6 +62,8 @@ function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onS Console.disableLoggingAndFlushLogs(); }; const styles = useThemeStyles(); + const [isConsoleModalVisible, setIsConsoleModalVisible] = useState(false); + return ( <> @@ -68,6 +73,15 @@ function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onS onToggle={onToggle} /> + {!!shouldStoreLogs && isViaTestToolsModal && + + - )} - {/** + + {isHidden ? translate('moderation.revealMessage') : translate('moderation.hideMessage')} + + + )} + {/** These are the actionable buttons that appear at the bottom of a Concierge message for example: Invite a user mentioned but not a member of the room https://github.com/Expensify/App/issues/32741 */} - {actionableItemButtons.length > 0 && ( - - )} - - ) : ( - - )} + {actionableItemButtons.length > 0 && ( + + )} + + ) : ( + + )} + ); } diff --git a/src/pages/home/report/ReportAttachments.tsx b/src/pages/home/report/ReportAttachments.tsx index 82b49d1e260c..e6dbd760e5af 100644 --- a/src/pages/home/report/ReportAttachments.tsx +++ b/src/pages/home/report/ReportAttachments.tsx @@ -6,13 +6,14 @@ import ComposerFocusManager from '@libs/ComposerFocusManager'; import Navigation from '@libs/Navigation/Navigation'; import type {AuthScreensParamList} from '@libs/Navigation/types'; import * as ReportUtils from '@libs/ReportUtils'; +import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; -type ReportAttachmentsProps = StackScreenProps; +type ReportAttachmentsProps = StackScreenProps; function ReportAttachments({route}: ReportAttachmentsProps) { - const reportID = route.params.reportID; + const reportID = route.params.id; const report = ReportUtils.getReport(reportID); // In native the imported images sources are of type number. Ref: https://reactnative.dev/docs/image#imagesource @@ -20,7 +21,7 @@ function ReportAttachments({route}: ReportAttachmentsProps) { const onCarouselAttachmentChange = useCallback( (attachment: Attachment) => { - const routeToNavigate = ROUTES.REPORT_ATTACHMENTS.getRoute(reportID, String(attachment.source)); + const routeToNavigate = ROUTES.ATTACHMENTS.getRoute(reportID, CONST.ATTACHMENT_TYPE.REPORT, String(attachment.source)); Navigation.navigate(routeToNavigate); }, [reportID], From 68f91157f2db2f337a342ea6244151f4ad0cd90f Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Thu, 25 Apr 2024 12:35:11 +0700 Subject: [PATCH 008/207] fix navigation issue --- src/ROUTES.ts | 3 +- src/components/AttachmentContext.ts | 15 ++-- src/components/AttachmentModal.tsx | 11 +++ .../extractAttachmentsFromNote.ts | 80 +++++++++++++++++++ .../Attachments/AttachmentCarousel/index.tsx | 20 +++-- .../Attachments/AttachmentCarousel/types.ts | 8 ++ .../HTMLRenderers/ImageRenderer.tsx | 14 ++-- src/libs/Middleware/SaveResponseInOnyx.ts | 2 +- src/libs/Navigation/NavigationRoot.tsx | 2 +- src/libs/Navigation/linkTo.ts | 10 +-- src/libs/Navigation/linkingConfig/config.ts | 1 - .../linkingConfig/getAdaptedStateFromPath.ts | 1 - src/libs/Navigation/types.ts | 3 +- .../PrivateNotes/PrivateNotesListPage.tsx | 10 ++- src/pages/home/report/ReportActionItem.tsx | 2 +- src/pages/home/report/ReportAttachments.tsx | 11 ++- 16 files changed, 152 insertions(+), 41 deletions(-) create mode 100644 src/components/Attachments/AttachmentCarousel/extractAttachmentsFromNote.ts diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 47fe2516c7d7..2e65cee4ebb0 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -227,7 +227,8 @@ const ROUTES = { }, ATTACHMENTS: { route: 'attachment', - getRoute: (id: string, type: ValueOf, url: string) => `attachment?source=${encodeURIComponent(url)}&type=${type}${id ? `&id=${id}` : ''}`, + getRoute: (reportID: string, type: ValueOf, url: string, accountID?: number) => + `attachment?source=${encodeURIComponent(url)}&type=${type}${reportID ? `&reportID=${reportID}` : ''}${accountID ? `&accountID=${accountID}` : ''}`, }, REPORT_PARTICIPANTS: { route: 'r/:reportID/participants', diff --git a/src/components/AttachmentContext.ts b/src/components/AttachmentContext.ts index 5fcb9ce7b0a4..4ed6bdc9084f 100644 --- a/src/components/AttachmentContext.ts +++ b/src/components/AttachmentContext.ts @@ -1,17 +1,22 @@ import {createContext} from 'react'; -import {ValueOf} from 'type-fest'; -import CONST from '@src/CONST'; +import type {ValueOf} from 'type-fest'; +import type CONST from '@src/CONST'; type AttachmentContextProps = { type?: ValueOf; - id?: string; + reportID?: string; + accountID?: number; }; const AttachmentContext = createContext({ type: undefined, - id: undefined, + reportID: undefined, + accountID: undefined, }); AttachmentContext.displayName = 'AttachmentContext'; -export {AttachmentContext}; +export { + // eslint-disable-next-line import/prefer-default-export + AttachmentContext, +}; diff --git a/src/components/AttachmentModal.tsx b/src/components/AttachmentModal.tsx index 7d13524b78df..39a4ead98e15 100644 --- a/src/components/AttachmentModal.tsx +++ b/src/components/AttachmentModal.tsx @@ -5,6 +5,7 @@ import {GestureHandlerRootView} from 'react-native-gesture-handler'; import {withOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; import {useSharedValue} from 'react-native-reanimated'; +import type {ValueOf} from 'type-fest'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useStyleUtils from '@hooks/useStyleUtils'; @@ -106,6 +107,12 @@ type AttachmentModalProps = AttachmentModalOnyxProps & { /** The report that has this attachment */ report?: OnyxEntry | EmptyObject; + /** The type of the attachment */ + type?: ValueOf; + + /** If the attachment originates from a note, the accountID will represent the author of that note. */ + accountID?: number; + /** Optional callback to fire when we want to do something after modal show. */ onModalShow?: () => void; @@ -163,6 +170,8 @@ function AttachmentModal({ onModalClose = () => {}, isLoading = false, shouldShowNotFoundPage = false, + type = undefined, + accountID = undefined, }: AttachmentModalProps) { const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); @@ -524,6 +533,8 @@ function AttachmentModal({ )} {!isEmptyObject(report) && !isReceiptAttachment ? ( { + if (name === 'video') { + const source = tryResolveUrlFromApiRoot(attribs[CONST.ATTACHMENT_SOURCE_ATTRIBUTE]); + if (uniqueSources.has(source)) { + return; + } + + uniqueSources.add(source); + const splittedUrl = attribs[CONST.ATTACHMENT_SOURCE_ATTRIBUTE].split('/'); + attachments.unshift({ + source: tryResolveUrlFromApiRoot(attribs[CONST.ATTACHMENT_SOURCE_ATTRIBUTE]), + isAuthTokenRequired: Boolean(attribs[CONST.ATTACHMENT_SOURCE_ATTRIBUTE]), + file: {name: splittedUrl[splittedUrl.length - 1]}, + duration: Number(attribs[CONST.ATTACHMENT_DURATION_ATTRIBUTE]), + isReceipt: false, + hasBeenFlagged: false, + }); + return; + } + + if (name === 'img' && attribs.src) { + const expensifySource = attribs[CONST.ATTACHMENT_SOURCE_ATTRIBUTE]; + const source = tryResolveUrlFromApiRoot(expensifySource || attribs.src); + if (uniqueSources.has(source)) { + return; + } + + uniqueSources.add(source); + let fileName = attribs[CONST.ATTACHMENT_ORIGINAL_FILENAME_ATTRIBUTE] || FileUtils.getFileName(`${source}`); + + // Public image URLs might lack a file extension in the source URL, without an extension our + // AttachmentView fails to recognize them as images and renders fallback content instead. + // We apply this small hack to add an image extension and ensure AttachmentView renders the image. + const fileInfo = FileUtils.splitExtensionFromFileName(fileName); + if (!fileInfo.fileExtension) { + fileName = `${fileInfo.fileName || 'image'}.jpg`; + } + + // By iterating actions in chronological order and prepending each attachment + // we ensure correct order of attachments even across actions with multiple attachments. + attachments.unshift({ + reportActionID: attribs['data-id'], + source, + isAuthTokenRequired: Boolean(expensifySource), + file: {name: fileName}, + isReceipt: false, + hasBeenFlagged: attribs['data-flagged'] === 'true', + }); + } + }, + }); + + htmlParser.write(targetNote); + htmlParser.end(); + + return attachments.reverse(); +} + +export default extractAttachmentsFromNote; diff --git a/src/components/Attachments/AttachmentCarousel/index.tsx b/src/components/Attachments/AttachmentCarousel/index.tsx index 3a7e0f19c4cd..64d694683b9b 100644 --- a/src/components/Attachments/AttachmentCarousel/index.tsx +++ b/src/components/Attachments/AttachmentCarousel/index.tsx @@ -19,6 +19,7 @@ import AttachmentCarouselCellRenderer from './AttachmentCarouselCellRenderer'; import CarouselActions from './CarouselActions'; import CarouselButtons from './CarouselButtons'; import CarouselItem from './CarouselItem'; +import extractAttachmentsFromNote from './extractAttachmentsFromNote'; import extractAttachmentsFromReport from './extractAttachmentsFromReport'; import type {AttachmentCaraouselOnyxProps, AttachmentCarouselProps, UpdatePageProps} from './types'; import useCarouselArrows from './useCarouselArrows'; @@ -29,7 +30,7 @@ const viewabilityConfig = { itemVisiblePercentThreshold: 95, }; -function AttachmentCarousel({report, reportActions, parentReportActions, source, onNavigate, setDownloadButtonVisibility}: AttachmentCarouselProps) { +function AttachmentCarousel({report, reportActions, parentReportActions, source, onNavigate, setDownloadButtonVisibility, type, accountID}: AttachmentCarouselProps) { const theme = useTheme(); const {translate} = useLocalize(); const styles = useThemeStyles(); @@ -49,19 +50,24 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source, useEffect(() => { const parentReportAction = report.parentReportActionID && parentReportActions ? parentReportActions[report.parentReportActionID] : undefined; const attachmentsFromReport = extractAttachmentsFromReport(parentReportAction, reportActions ?? undefined); + let attachmentsFromNote: Attachment[] = []; + if (type === CONST.ATTACHMENT_TYPE.NOTE && accountID) { + attachmentsFromNote = extractAttachmentsFromNote(report.reportID, accountID); + } + const targetAttachments = type === CONST.ATTACHMENT_TYPE.REPORT ? attachmentsFromReport : attachmentsFromNote; - if (isEqual(attachments, attachmentsFromReport)) { + if (isEqual(attachments, targetAttachments)) { return; } - const initialPage = attachmentsFromReport.findIndex(compareImage); + const initialPage = targetAttachments.findIndex(compareImage); // Dismiss the modal when deleting an attachment during its display in preview. if (initialPage === -1 && attachments.find(compareImage)) { Navigation.dismissModal(); } else { setPage(initialPage); - setAttachments(attachmentsFromReport); + setAttachments(targetAttachments); // Update the download button visibility in the parent modal if (setDownloadButtonVisibility) { @@ -69,11 +75,11 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source, } // Update the parent modal's state with the source and name from the mapped attachments - if (attachmentsFromReport[initialPage] !== undefined && onNavigate) { - onNavigate(attachmentsFromReport[initialPage]); + if (targetAttachments[initialPage] !== undefined && onNavigate) { + onNavigate(targetAttachments[initialPage]); } } - }, [reportActions, parentReportActions, compareImage, report.parentReportActionID, attachments, setDownloadButtonVisibility, onNavigate]); + }, [reportActions, parentReportActions, compareImage, report.parentReportActionID, attachments, setDownloadButtonVisibility, onNavigate, accountID, report.reportID]); /** Updates the page state when the user navigates between attachments */ const updatePage = useCallback( diff --git a/src/components/Attachments/AttachmentCarousel/types.ts b/src/components/Attachments/AttachmentCarousel/types.ts index 8ba3489a5fcf..d31ebbd328cd 100644 --- a/src/components/Attachments/AttachmentCarousel/types.ts +++ b/src/components/Attachments/AttachmentCarousel/types.ts @@ -1,6 +1,8 @@ import type {ViewToken} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; +import type {ValueOf} from 'type-fest'; import type {Attachment, AttachmentSource} from '@components/Attachments/types'; +import type CONST from '@src/CONST'; import type {Report, ReportActions} from '@src/types/onyx'; type UpdatePageProps = { @@ -28,6 +30,12 @@ type AttachmentCarouselProps = AttachmentCaraouselOnyxProps & { /** The report currently being looked at */ report: Report; + /** The type of the attachment */ + type?: ValueOf; + + /** If the attachment originates from a note, the accountID will represent the author of that note. */ + accountID?: number; + /** A callback that is called when swipe-down-to-close gesture happens */ onClose: () => void; }; diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx index 4e78f127d06c..36238d635d83 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx +++ b/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx @@ -80,17 +80,19 @@ function ImageRenderer({tnode}: ImageRendererProps) { {({anchor, report, action, checkIfContextMenuActive}) => ( - {({id, type}) => ( + {({reportID, accountID, type}) => ( { + if (!source || !type) { + return; + } let route = ''; - if (source && type) { - if (id) { - route = ROUTES.ATTACHMENTS?.getRoute(id, type, source); - Navigation.navigate(route); - } + if (reportID) { + route = ROUTES.ATTACHMENTS?.getRoute(reportID, type, source, accountID); } + + Navigation.navigate(route); }} onLongPress={(event) => showContextMenuForReport(event, anchor, report?.reportID ?? '', action, checkIfContextMenuActive, ReportUtils.isArchivedRoom(report))} shouldUseHapticsOnLongPress diff --git a/src/libs/Middleware/SaveResponseInOnyx.ts b/src/libs/Middleware/SaveResponseInOnyx.ts index 58052c971505..4f06f206eb37 100644 --- a/src/libs/Middleware/SaveResponseInOnyx.ts +++ b/src/libs/Middleware/SaveResponseInOnyx.ts @@ -33,7 +33,7 @@ const SaveResponseInOnyx: Middleware = (requestResponse, request) => OnyxUpdates.saveUpdateInformation(responseToApply); // Ensure the queue is paused while the client resolves the gap in onyx updates so that updates are guaranteed to happen in a specific order. - console.log("**********************", {command: request.command}) + return Promise.resolve({ ...response, shouldPauseQueue: true, diff --git a/src/libs/Navigation/NavigationRoot.tsx b/src/libs/Navigation/NavigationRoot.tsx index 4c3084c5291a..f143d6b2bcc1 100644 --- a/src/libs/Navigation/NavigationRoot.tsx +++ b/src/libs/Navigation/NavigationRoot.tsx @@ -118,7 +118,7 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady}: N if (!state) { return; } - console.log("777777777", state.routes) + const activeWorkspaceID = getPolicyIDFromState(state as NavigationState); // Performance optimization to avoid context consumers to delay first render setTimeout(() => { diff --git a/src/libs/Navigation/linkTo.ts b/src/libs/Navigation/linkTo.ts index e644127cac61..e08237c04601 100644 --- a/src/libs/Navigation/linkTo.ts +++ b/src/libs/Navigation/linkTo.ts @@ -148,23 +148,20 @@ export default function linkTo(navigation: NavigationContainerRef const onboardingModalNavigator = state.routes.find((route) => route.name === NAVIGATORS.ONBOARDING_MODAL_NAVIGATOR); const welcomeVideoModalNavigator = state.routes.find((route) => route.name === NAVIGATORS.WELCOME_VIDEO_MODAL_NAVIGATOR); const attachmentsScreen = state.routes.find((route) => route.name === SCREENS.ATTACHMENTS); - console.log('9999999999', state.routes); if (isNarrowLayout) { metainfo.isFullScreenNavigatorMandatory = false; diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index b0df6085aff8..20e1be99d5a1 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -768,9 +768,10 @@ type AuthScreensParamList = SharedScreensParamList & { [NAVIGATORS.CENTRAL_PANE_NAVIGATOR]: NavigatorScreenParams; [SCREENS.CONCIERGE]: undefined; [SCREENS.ATTACHMENTS]: { - id: string; + reportID: string; source: string; type: ValueOf; + accountID: string; }; [SCREENS.PROFILE_AVATAR]: { accountID: string; diff --git a/src/pages/PrivateNotes/PrivateNotesListPage.tsx b/src/pages/PrivateNotes/PrivateNotesListPage.tsx index f8121af32076..286c91d628fd 100644 --- a/src/pages/PrivateNotes/PrivateNotesListPage.tsx +++ b/src/pages/PrivateNotes/PrivateNotesListPage.tsx @@ -1,4 +1,4 @@ -import React, {useMemo} from 'react'; +import React, {useCallback, useMemo} from 'react'; import {withOnyx} from 'react-native-onyx'; import type {OnyxCollection} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; @@ -30,24 +30,26 @@ type PrivateNotesListPageProps = WithReportAndPrivateNotesOrNotFoundProps & }; type NoteListItem = { - id: string; title: string; action: () => void; brickRoadIndicator: ValueOf | undefined; note: string; disabled: boolean; + reportID: string; + accountID: string; }; function PrivateNotesListPage({report, personalDetailsList, session}: PrivateNotesListPageProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); + const getAttachmentValue = useCallback((item: NoteListItem) => ({reportID: item.reportID, accountID: Number(item.accountID), type: CONST.ATTACHMENT_TYPE.NOTE}), []); /** * Gets the menu item for each workspace */ function getMenuItem(item: NoteListItem) { return ( - + { const privateNote = report.privateNotes?.[Number(accountID)]; return { + reportID: report.reportID, + accountID, title: Number(session?.accountID) === Number(accountID) ? translate('privateNotes.myNote') : personalDetailsList?.[accountID]?.login ?? '', action: () => Navigation.navigate(ROUTES.PRIVATE_NOTES_EDIT.getRoute(report.reportID, accountID)), brickRoadIndicator: privateNoteBrickRoadIndicator(Number(accountID)), diff --git a/src/pages/home/report/ReportActionItem.tsx b/src/pages/home/report/ReportActionItem.tsx index df303b763282..60b86c209c68 100644 --- a/src/pages/home/report/ReportActionItem.tsx +++ b/src/pages/home/report/ReportActionItem.tsx @@ -374,7 +374,7 @@ function ReportActionItem({ [report, action, toggleContextMenuFromActiveReportAction, transactionThreadReport], ); - const attachmentContextValue = useMemo(() => ({id: report.reportID, type: CONST.ATTACHMENT_TYPE.REPORT}), [report.reportID]); + const attachmentContextValue = useMemo(() => ({reportID: report.reportID, type: CONST.ATTACHMENT_TYPE.REPORT}), [report.reportID]); const actionableItemButtons: ActionableItem[] = useMemo(() => { const isWhisperResolution = (action?.originalMessage as OriginalMessageActionableMentionWhisper['originalMessage'])?.resolution !== null; diff --git a/src/pages/home/report/ReportAttachments.tsx b/src/pages/home/report/ReportAttachments.tsx index e6dbd760e5af..3ff472baee40 100644 --- a/src/pages/home/report/ReportAttachments.tsx +++ b/src/pages/home/report/ReportAttachments.tsx @@ -6,14 +6,15 @@ import ComposerFocusManager from '@libs/ComposerFocusManager'; import Navigation from '@libs/Navigation/Navigation'; import type {AuthScreensParamList} from '@libs/Navigation/types'; import * as ReportUtils from '@libs/ReportUtils'; -import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; type ReportAttachmentsProps = StackScreenProps; function ReportAttachments({route}: ReportAttachmentsProps) { - const reportID = route.params.id; + const reportID = route.params.reportID; + const type = route.params.type; + const accountID = route.params.accountID; const report = ReportUtils.getReport(reportID); // In native the imported images sources are of type number. Ref: https://reactnative.dev/docs/image#imagesource @@ -21,14 +22,16 @@ function ReportAttachments({route}: ReportAttachmentsProps) { const onCarouselAttachmentChange = useCallback( (attachment: Attachment) => { - const routeToNavigate = ROUTES.ATTACHMENTS.getRoute(reportID, CONST.ATTACHMENT_TYPE.REPORT, String(attachment.source)); + const routeToNavigate = ROUTES.ATTACHMENTS.getRoute(reportID, type, String(attachment.source), Number(accountID)); Navigation.navigate(routeToNavigate); }, - [reportID], + [reportID, accountID, type], ); return ( Date: Thu, 25 Apr 2024 12:36:21 +0700 Subject: [PATCH 009/207] fix remove unused change --- src/libs/Middleware/SaveResponseInOnyx.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/Middleware/SaveResponseInOnyx.ts b/src/libs/Middleware/SaveResponseInOnyx.ts index 4f06f206eb37..ffe4f8a9bea9 100644 --- a/src/libs/Middleware/SaveResponseInOnyx.ts +++ b/src/libs/Middleware/SaveResponseInOnyx.ts @@ -33,7 +33,6 @@ const SaveResponseInOnyx: Middleware = (requestResponse, request) => OnyxUpdates.saveUpdateInformation(responseToApply); // Ensure the queue is paused while the client resolves the gap in onyx updates so that updates are guaranteed to happen in a specific order. - return Promise.resolve({ ...response, shouldPauseQueue: true, From 07cb16f10664cdb345647401804793d455b2ef9a Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Thu, 25 Apr 2024 12:38:18 +0700 Subject: [PATCH 010/207] fix remove unused change --- src/libs/Navigation/NavigationRoot.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/Navigation/NavigationRoot.tsx b/src/libs/Navigation/NavigationRoot.tsx index f143d6b2bcc1..506eae2bdfd2 100644 --- a/src/libs/Navigation/NavigationRoot.tsx +++ b/src/libs/Navigation/NavigationRoot.tsx @@ -118,7 +118,6 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady}: N if (!state) { return; } - const activeWorkspaceID = getPolicyIDFromState(state as NavigationState); // Performance optimization to avoid context consumers to delay first render setTimeout(() => { From 8d8867d24826a754f7abf6d1078dfb8a78c5f600 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Thu, 25 Apr 2024 14:32:11 +0700 Subject: [PATCH 011/207] fix remove unused change --- src/libs/Navigation/linkTo.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Navigation/linkTo.ts b/src/libs/Navigation/linkTo.ts index e08237c04601..863cb102add4 100644 --- a/src/libs/Navigation/linkTo.ts +++ b/src/libs/Navigation/linkTo.ts @@ -154,6 +154,7 @@ export default function linkTo(navigation: NavigationContainerRef Date: Thu, 25 Apr 2024 14:42:53 +0700 Subject: [PATCH 012/207] fix typecheck --- src/ROUTES.ts | 2 +- .../HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx | 7 +++---- .../Navigation/linkingConfig/getAdaptedStateFromPath.ts | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 249ba1c2571a..a1c609db6217 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -223,7 +223,7 @@ const ROUTES = { ATTACHMENTS: { route: 'attachment', getRoute: (reportID: string, type: ValueOf, url: string, accountID?: number) => - `attachment?source=${encodeURIComponent(url)}&type=${type}${reportID ? `&reportID=${reportID}` : ''}${accountID ? `&accountID=${accountID}` : ''}`, + `attachment?source=${encodeURIComponent(url)}&type=${type}${reportID ? `&reportID=${reportID}` : ''}${accountID ? `&accountID=${accountID}` : ''}` as const, }, REPORT_PARTICIPANTS: { route: 'r/:reportID/participants', diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx index 36238d635d83..221731bbeef6 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx +++ b/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx @@ -87,12 +87,11 @@ function ImageRenderer({tnode}: ImageRendererProps) { if (!source || !type) { return; } - let route = ''; + if (reportID) { - route = ROUTES.ATTACHMENTS?.getRoute(reportID, type, source, accountID); + const route = ROUTES.ATTACHMENTS?.getRoute(reportID, type, source, accountID); + Navigation.navigate(route); } - - Navigation.navigate(route); }} onLongPress={(event) => showContextMenuForReport(event, anchor, report?.reportID ?? '', action, checkIfContextMenuActive, ReportUtils.isArchivedRoom(report))} shouldUseHapticsOnLongPress diff --git a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts index 4faa12696726..9a951bc4f9f2 100644 --- a/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts +++ b/src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts @@ -306,7 +306,7 @@ function getAdaptedState(state: PartialState const matchingBottomTabRoute = getMatchingBottomTabRouteForState(state); routes.push(createBottomTabNavigator(matchingBottomTabRoute, policyID)); if (!isNarrowLayout) { - routes.push(createCentralPaneNavigator({name: SCREENS.REPORT, params: {reportID: reportAttachments.params?.id ?? ''}})); + routes.push(createCentralPaneNavigator({name: SCREENS.REPORT, params: {reportID: reportAttachments.params?.reportID ?? ''}})); } routes.push(reportAttachments); From c48b0aa66fccfbdf9e84733e8bdeb08a1b4a57f0 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Thu, 25 Apr 2024 14:49:50 +0700 Subject: [PATCH 013/207] fix lint --- src/components/Attachments/AttachmentCarousel/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Attachments/AttachmentCarousel/index.tsx b/src/components/Attachments/AttachmentCarousel/index.tsx index 64d694683b9b..6e8843472377 100644 --- a/src/components/Attachments/AttachmentCarousel/index.tsx +++ b/src/components/Attachments/AttachmentCarousel/index.tsx @@ -79,7 +79,7 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source, onNavigate(targetAttachments[initialPage]); } } - }, [reportActions, parentReportActions, compareImage, report.parentReportActionID, attachments, setDownloadButtonVisibility, onNavigate, accountID, report.reportID]); + }, [reportActions, parentReportActions, compareImage, report.parentReportActionID, attachments, setDownloadButtonVisibility, onNavigate, accountID, report.reportID, type]); /** Updates the page state when the user navigates between attachments */ const updatePage = useCallback( From aef525237d188ca52a7256b45bc2ece9f680f3d4 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Thu, 25 Apr 2024 15:39:59 +0700 Subject: [PATCH 014/207] fix native issue --- .../AttachmentCarousel/index.native.tsx | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/components/Attachments/AttachmentCarousel/index.native.tsx b/src/components/Attachments/AttachmentCarousel/index.native.tsx index f6d63fc9307d..c97b16ca2988 100644 --- a/src/components/Attachments/AttachmentCarousel/index.native.tsx +++ b/src/components/Attachments/AttachmentCarousel/index.native.tsx @@ -9,15 +9,17 @@ import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; import variables from '@styles/variables'; +import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import CarouselButtons from './CarouselButtons'; +import extractAttachmentsFromNote from './extractAttachmentsFromNote'; import extractAttachmentsFromReport from './extractAttachmentsFromReport'; import type {AttachmentCarouselPagerHandle} from './Pager'; import AttachmentCarouselPager from './Pager'; import type {AttachmentCaraouselOnyxProps, AttachmentCarouselProps} from './types'; import useCarouselArrows from './useCarouselArrows'; -function AttachmentCarousel({report, reportActions, parentReportActions, source, onNavigate, setDownloadButtonVisibility, onClose}: AttachmentCarouselProps) { +function AttachmentCarousel({report, reportActions, parentReportActions, source, onNavigate, setDownloadButtonVisibility, onClose, type, accountID}: AttachmentCarouselProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); const pagerRef = useRef(null); @@ -31,15 +33,19 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source, useEffect(() => { const parentReportAction = report.parentReportActionID && parentReportActions ? parentReportActions[report.parentReportActionID] : undefined; const attachmentsFromReport = extractAttachmentsFromReport(parentReportAction, reportActions); - - const initialPage = attachmentsFromReport.findIndex(compareImage); + let attachmentsFromNote: Attachment[] = []; + if (type === CONST.ATTACHMENT_TYPE.NOTE && accountID) { + attachmentsFromNote = extractAttachmentsFromNote(report.reportID, accountID); + } + const targetAttachments = type === CONST.ATTACHMENT_TYPE.REPORT ? attachmentsFromReport : attachmentsFromNote; + const initialPage = targetAttachments.findIndex(compareImage); // Dismiss the modal when deleting an attachment during its display in preview. if (initialPage === -1 && attachments.find(compareImage)) { Navigation.dismissModal(); } else { setPage(initialPage); - setAttachments(attachmentsFromReport); + setAttachments(targetAttachments); // Update the download button visibility in the parent modal if (setDownloadButtonVisibility) { @@ -47,8 +53,8 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source, } // Update the parent modal's state with the source and name from the mapped attachments - if (attachmentsFromReport[initialPage] !== undefined && onNavigate) { - onNavigate(attachmentsFromReport[initialPage]); + if (targetAttachments[initialPage] !== undefined && onNavigate) { + onNavigate(targetAttachments[initialPage]); } } // eslint-disable-next-line react-hooks/exhaustive-deps From 851f959154367ef5b46d71dcad94061e59078e8f Mon Sep 17 00:00:00 2001 From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com> Date: Mon, 29 Apr 2024 16:57:03 +0530 Subject: [PATCH 015/207] Navigate to console page --- src/CONST.ts | 1 - src/ROUTES.ts | 5 +- .../BaseClientSideLoggingToolMenu.tsx | 22 +- .../ConsoleComponents.tsx | 193 ------------------ .../ConsoleModal.tsx | 44 ---- .../index.android.tsx | 2 +- .../ClientSideLoggingToolMenu/index.ios.tsx | 2 +- .../ClientSideLoggingToolMenu/index.tsx | 2 +- .../ClientSideLoggingToolMenu/types.ts | 2 - src/components/Modal/index.tsx | 2 +- src/components/TestToolsModal.tsx | 5 +- src/libs/Navigation/linkingConfig/config.ts | 2 +- src/libs/Navigation/types.ts | 4 +- src/pages/settings/AboutPage/ConsolePage.tsx | 179 +++++++++++++++- .../ShareLogList/BaseShareLogList.tsx | 8 +- .../AboutPage/ShareLogList/index.native.tsx | 4 +- .../settings/AboutPage/ShareLogList/index.tsx | 7 +- src/pages/settings/AboutPage/ShareLogPage.tsx | 7 +- .../Troubleshoot/TroubleshootPage.tsx | 2 +- .../utils/generators/ModalStyleUtils.ts | 23 --- 20 files changed, 214 insertions(+), 302 deletions(-) delete mode 100644 src/components/ClientSideLoggingToolMenu/ConsoleComponents.tsx delete mode 100644 src/components/ClientSideLoggingToolMenu/ConsoleModal.tsx diff --git a/src/CONST.ts b/src/CONST.ts index 893dc008786b..2cd614b74816 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -860,7 +860,6 @@ const CONST = { POPOVER: 'popover', RIGHT_DOCKED: 'right_docked', ONBOARDING: 'onboarding', - CENTERED_SMALL_AND_UNSWIPEABLE: 'centered_small_and_unswipeable' }, ANCHOR_ORIGIN_VERTICAL: { TOP: 'top', diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 71e673aea994..db9ae77fd0e8 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -172,7 +172,10 @@ const ROUTES = { SETTINGS_STATUS_CLEAR_AFTER_DATE: 'settings/profile/status/clear-after/date', SETTINGS_STATUS_CLEAR_AFTER_TIME: 'settings/profile/status/clear-after/time', SETTINGS_TROUBLESHOOT: 'settings/troubleshoot', - SETTINGS_CONSOLE: 'settings/troubleshoot/console', + SETTINGS_CONSOLE: { + route: 'settings/troubleshoot/console', + getRoute: (isViaTestToolsModal = false) => `settings/troubleshoot/console?isViaTestToolsModal=${isViaTestToolsModal}` as const, + }, SETTINGS_SHARE_LOG: { route: 'settings/troubleshoot/console/share-log', getRoute: (source: string, isViaTestToolsModal = false) => `settings/troubleshoot/console/share-log?source=${encodeURI(source)}&isViaTestToolsModal=${isViaTestToolsModal}` as const, diff --git a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx index 9b5faac55bc4..7d27caa997f7 100644 --- a/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx +++ b/src/components/ClientSideLoggingToolMenu/BaseClientSideLoggingToolMenu.tsx @@ -1,4 +1,4 @@ -import React, {useState} from 'react'; +import React from 'react'; import {Alert} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; @@ -12,7 +12,8 @@ import * as Console from '@libs/actions/Console'; import {parseStringifiedMessages} from '@libs/Console'; import ONYXKEYS from '@src/ONYXKEYS'; import type {CapturedLogs, Log} from '@src/types/onyx'; -import ConsoleModal from "./ConsoleModal"; +import Navigation from "@navigation/Navigation"; +import ROUTES from "@src/ROUTES"; type BaseClientSideLoggingToolMenuOnyxProps = { /** Logs captured on the current device */ @@ -64,7 +65,6 @@ function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onS Console.disableLoggingAndFlushLogs(); }; const styles = useThemeStyles(); - const [isConsoleModalVisible, setIsConsoleModalVisible] = useState(false); return ( <> @@ -75,15 +75,18 @@ function BaseClientSideLoggingToolMenu({shouldStoreLogs, capturedLogs, file, onS onToggle={onToggle} /> - {!!shouldStoreLogs && isViaTestToolsModal && + {!!shouldStoreLogs && isViaTestToolsModal && (