Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
68eb38b
refactor: migrate AttachmentModal usages to AttachmentModalScreen
chrispader Jun 6, 2025
0f44f86
Merge branch 'main' into @chrispader/migrate-attachment-modals-to-mod…
chrispader Jun 11, 2025
4dbf5b4
fix: add back FileObject type
chrispader Jun 11, 2025
5458b87
fix: typos
chrispader Jun 11, 2025
007313e
fix: typo
chrispader Jun 11, 2025
e253d38
fix: eslint check, `getPolicy` deprecated
chrispader Jun 11, 2025
603fbb3
refactor: remove changes not related to `ReportAttachments` screen
chrispader Jun 11, 2025
dd6e292
fix: remove code out of scope for this PR
chrispader Jun 11, 2025
1f2a9f0
add back route files
chrispader Jun 11, 2025
1f9de8f
Delete SvgIconComponent.ts
chrispader Jun 11, 2025
323cb15
fix: remove add attachment related change
chrispader Jun 11, 2025
0d8d181
Merge branch 'main' into @chrispader/migrate-attachment-modals-to-mod…
chrispader Jun 11, 2025
85f2468
fix: PureReportActionItem should be a pure function
chrispader Jun 11, 2025
eceec08
fix: remove unnecessary policy param
chrispader Jun 11, 2025
6c2f5e2
Merge branch 'main' into @chrispader/migrate-attachment-modals-to-mod…
chrispader Jun 16, 2025
865cfde
Merge branch 'main' into @chrispader/migrate-attachment-modals-to-mod…
chrispader Jun 19, 2025
f37d25e
Merge branch 'main' into @chrispader/migrate-attachment-modals-to-mod…
chrispader Jun 23, 2025
596f100
revert: remove other attachment modal screen routes
chrispader Jun 23, 2025
54dc4e9
feat: add back modalScreenListener
chrispader Jun 23, 2025
7866773
refactor: remove extra route from ReportsSplitNavigator
chrispader Jun 23, 2025
3bbde51
refactor: onClose and fix no modal out animation
chrispader Jun 23, 2025
0a0998f
fix: 61485 Go back from invalid policy on link press
chrispader Jun 24, 2025
3b873aa
Merge branch 'main' into @chrispader/migrate-attachment-modals-to-mod…
chrispader Jun 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import {CurrentReportIDContextProvider} from './hooks/useCurrentReportID';
import useDefaultDragAndDrop from './hooks/useDefaultDragAndDrop';
import HybridAppHandler from './HybridAppHandler';
import OnyxUpdateManager from './libs/actions/OnyxUpdateManager';
import {ReportAttachmentsProvider} from './pages/home/report/ReportAttachmentsContext';
import {AttachmentModalContextProvider} from './pages/media/AttachmentModalScreen/AttachmentModalContext';
import type {Route} from './ROUTES';
import './setup/backgroundTask';
import './setup/hybridApp';
Expand Down Expand Up @@ -95,7 +95,7 @@ function App({url, hybridAppSettings}: AppProps) {
PopoverContextProvider,
CurrentReportIDContextProvider,
ScrollOffsetContextProvider,
ReportAttachmentsProvider,
AttachmentModalContextProvider,
PickerStateProvider,
EnvironmentProvider,
CustomStatusBarAndBackgroundContextProvider,
Expand Down
50 changes: 27 additions & 23 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {IOUAction, IOUType} from './CONST';
import type {IOURequestType} from './libs/actions/IOU';
import Log from './libs/Log';
import type {ReimbursementAccountStepToOpen} from './libs/ReimbursementAccountUtils';
import type {AttachmentModalScreenParams} from './pages/media/AttachmentModalScreen/types';
import SCREENS from './SCREENS';
import type {Screen} from './SCREENS';
import type {ExitReason} from './types/form/ExitSurveyReasonForm';
Expand Down Expand Up @@ -443,28 +444,7 @@ const ROUTES = {
},
ATTACHMENTS: {
route: 'attachment',
getRoute: (
reportID: string | undefined,
attachmentID: string | undefined,
type: ValueOf<typeof CONST.ATTACHMENT_TYPE> | undefined,
url: string,
accountID?: number,
isAuthTokenRequired?: boolean,
fileName?: string,
attachmentLink?: string,
hashKey?: number,
) => {
const typeParam = type ? `&type=${type}` : '';
const reportParam = reportID ? `&reportID=${reportID}` : '';
const accountParam = accountID ? `&accountID=${accountID}` : '';
const authTokenParam = isAuthTokenRequired ? '&isAuthTokenRequired=true' : '';
const fileNameParam = fileName ? `&fileName=${fileName}` : '';
const attachmentLinkParam = attachmentLink ? `&attachmentLink=${attachmentLink}` : '';
const attachmentIDParam = attachmentID ? `&attachmentID=${attachmentID}` : '';
const hashKeyParam = hashKey ? `&hashKey=${hashKey}` : '';

return `attachment?source=${encodeURIComponent(url)}${typeParam}${reportParam}${attachmentIDParam}${accountParam}${authTokenParam}${fileNameParam}${attachmentLinkParam}${hashKeyParam}` as const;
},
getRoute: (params?: AttachmentRouteParams) => getAttachmentModalScreenRoute('attachment', params),
},
REPORT_PARTICIPANTS: {
route: 'r/:reportID/participants',
Expand All @@ -484,7 +464,7 @@ const ROUTES = {
},
REPORT_WITH_ID_DETAILS: {
route: 'r/:reportID/details',
getRoute: (reportID: string | undefined, backTo?: string) => {
getRoute: (reportID: string | number | undefined, backTo?: string) => {
if (!reportID) {
Log.warn('Invalid reportID is used to build the REPORT_WITH_ID_DETAILS route');
}
Expand Down Expand Up @@ -2634,6 +2614,30 @@ const SHARED_ROUTE_PARAMS: Partial<Record<Screen, string[]>> = {
export {HYBRID_APP_ROUTES, getUrlWithBackToParam, PUBLIC_SCREENS_ROUTES, SHARED_ROUTE_PARAMS};
export default ROUTES;

type AttachmentsRoute = typeof ROUTES.ATTACHMENTS.route;
type ReportAddAttachmentRoute = `r/${string}/attachment/add`;
type AttachmentRoutes = AttachmentsRoute | ReportAddAttachmentRoute;
type AttachmentRouteParams = AttachmentModalScreenParams;

function getAttachmentModalScreenRoute(url: AttachmentRoutes, params?: AttachmentRouteParams) {
if (!params?.source) {
return url;
}

const {source, attachmentID, type, reportID, accountID, isAuthTokenRequired, originalFileName, attachmentLink} = params;

const sourceParam = `?source=${encodeURIComponent(source as string)}`;
const attachmentIDParam = attachmentID ? `&attachmentID=${attachmentID}` : '';
const typeParam = type ? `&type=${type as string}` : '';
const reportIDParam = reportID ? `&reportID=${reportID}` : '';
const accountIDParam = accountID ? `&accountID=${accountID}` : '';
const authTokenParam = isAuthTokenRequired ? '&isAuthTokenRequired=true' : '';
const fileNameParam = originalFileName ? `&originalFileName=${originalFileName}` : '';
const attachmentLinkParam = attachmentLink ? `&attachmentLink=${attachmentLink}` : '';

return `${url}${sourceParam}${typeParam}${reportIDParam}${attachmentIDParam}${accountIDParam}${authTokenParam}${fileNameParam}${attachmentLinkParam} ` as const;
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
type ExtractRouteName<TRoute> = TRoute extends {getRoute: (...args: any[]) => infer TRouteName} ? TRouteName : TRoute;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import SafeAreaConsumer from '@components/SafeAreaConsumer';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import ReportAttachmentsContext from '@pages/home/report/ReportAttachmentsContext';
import AttachmentModalContext from '@pages/media/AttachmentModalScreen/AttachmentModalContext';
import CONST from '@src/CONST';

type CarouselItemProps = {
Expand All @@ -33,7 +33,7 @@ type CarouselItemProps = {
function CarouselItem({item, onPress, isFocused, isModalHovered, reportID}: CarouselItemProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const {isAttachmentHidden} = useContext(ReportAttachmentsContext);
const {isAttachmentHidden} = useContext(AttachmentModalContext);
const [isHidden, setIsHidden] = useState(() => (item.reportActionID && isAttachmentHidden(item.reportActionID)) ?? item.hasBeenFlagged);

const renderButton = (style: StyleProp<ViewStyle>) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,16 @@ function ImageRenderer({tnode}: ImageRendererProps) {
}

const attachmentLink = tnode.parent?.attributes?.href;
const route = ROUTES.ATTACHMENTS?.getRoute(reportID, attachmentID, type, source, accountID, isAttachmentOrReceipt, fileName, attachmentLink);
const route = ROUTES.ATTACHMENTS?.getRoute({
attachmentID,
reportID,
type,
source,
accountID,
isAuthTokenRequired: isAttachmentOrReceipt,
originalFileName: fileName,
attachmentLink,
});
Navigation.navigate(route);
}}
onLongPress={(event) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function VideoRenderer({tnode, key}: VideoRendererProps) {
return;
}
const isAuthTokenRequired = !!htmlAttribs[CONST.ATTACHMENT_SOURCE_ATTRIBUTE];
const route = ROUTES.ATTACHMENTS.getRoute(report?.reportID, attachmentID, type, sourceURL, accountID, isAuthTokenRequired, undefined, undefined, hashKey);
const route = ROUTES.ATTACHMENTS.getRoute({attachmentID, reportID: report?.reportID, type, source: sourceURL, accountID, isAuthTokenRequired, hashKey});
Navigation.navigate(route);
}}
/>
Expand Down
12 changes: 5 additions & 7 deletions src/libs/Navigation/AppNavigator/AuthScreens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import type {SelectedTimezone, Timezone} from '@src/types/onyx/PersonalDetails';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import type ReactComponentModule from '@src/types/utils/ReactComponentModule';
import attachmentModalScreenOptions from './attachmentModalScreenOptions';
import createRootStackNavigator from './createRootStackNavigator';
import {screensWithEnteringAnimation, workspaceSplitsWithoutEnteringAnimation} from './createRootStackNavigator/GetStateForActionHandlers';
import defaultScreenOptions from './defaultScreenOptions';
Expand All @@ -88,7 +89,7 @@
initialLastUpdateIDAppliedToClient: OnyxEntry<number>;
};

const loadReportAttachments = () => require<ReactComponentModule>('../../../pages/home/report/ReportAttachments').default;
const loadAttachmentModalScreen = () => require<ReactComponentModule>('../../../pages/media/AttachmentModalScreen').default;
const loadValidateLoginPage = () => require<ReactComponentModule>('../../../pages/ValidateLoginPage').default;
const loadLogOutPreviousUserPage = () => require<ReactComponentModule>('../../../pages/LogOutPreviousUserPage').default;
const loadConciergePage = () => require<ReactComponentModule>('../../../pages/ConciergePage').default;
Expand Down Expand Up @@ -120,7 +121,7 @@
let isLoadingApp = false;
let lastUpdateIDAppliedToClient: OnyxEntry<number>;

Onyx.connect({

Check warning on line 124 in src/libs/Navigation/AppNavigator/AuthScreens.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.SESSION,
callback: (value) => {
// When signed out, val hasn't accountID
Expand All @@ -139,7 +140,7 @@
},
});

Onyx.connect({

Check warning on line 143 in src/libs/Navigation/AppNavigator/AuthScreens.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.PERSONAL_DETAILS_LIST,
callback: (value) => {
if (!value || !isEmptyObject(timezone)) {
Expand All @@ -160,14 +161,14 @@
},
});

Onyx.connect({

Check warning on line 164 in src/libs/Navigation/AppNavigator/AuthScreens.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.IS_LOADING_APP,
callback: (value) => {
isLoadingApp = !!value;
},
});

Onyx.connect({

Check warning on line 171 in src/libs/Navigation/AppNavigator/AuthScreens.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT,
callback: (value) => {
lastUpdateIDAppliedToClient = value;
Expand All @@ -184,11 +185,11 @@
}

const RootStack = createRootStackNavigator<AuthScreensParamList>();

// We want to delay the re-rendering for components(e.g. ReportActionCompose)
// that depends on modal visibility until Modal is completely closed and its focused
// When modal screen is focused, update modal visibility in Onyx
// https://reactnavigation.org/docs/navigation-events/

const modalScreenListeners = {
focus: () => {
Modal.setModalVisibility(true, CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED);
Expand Down Expand Up @@ -600,11 +601,8 @@
/>
<RootStack.Screen
name={SCREENS.ATTACHMENTS}
options={{
headerShown: false,
presentation: Presentation.TRANSPARENT_MODAL,
}}
getComponent={loadReportAttachments}
options={attachmentModalScreenOptions}
getComponent={loadAttachmentModalScreen}
listeners={modalScreenListeners}
/>
<RootStack.Screen
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import type ReactComponentModule from '@src/types/utils/ReactComponentModule';

const loadReportScreen = () => require<ReactComponentModule>('@pages/home/ReportScreen').default;
const loadSidebarScreen = () => require<ReactComponentModule>('@pages/home/sidebar/BaseSidebarScreen').default;

const Split = createSplitNavigator<ReportsSplitNavigatorParamList>();

/**
Expand Down
3 changes: 3 additions & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1761,6 +1761,7 @@ type ReportsSplitNavigatorParamList = {
moneyRequestReportActionID?: string;
transactionID?: string;
};
[SCREENS.ATTACHMENTS]: AttachmentModalScreenParams;
};

type SettingsSplitNavigatorParamList = {
Expand Down Expand Up @@ -1968,6 +1969,7 @@ type SharedScreensParamList = {
shortLivedAuthToken?: string;
shortLivedToken?: string;
authTokenType?: ValueOf<typeof CONST.AUTH_TOKEN_TYPES>;
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
exitTo?: Routes | HybridAppRoute;
shouldForceLogin: string;
domain?: Routes;
Expand All @@ -1976,6 +1978,7 @@ type SharedScreensParamList = {
[SCREENS.VALIDATE_LOGIN]: {
accountID: string;
validateCode: string;
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
exitTo?: Routes | HybridAppRoute;
};
};
Expand Down
4 changes: 2 additions & 2 deletions src/pages/home/report/PureReportActionItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ import {
import SelectionScraper from '@libs/SelectionScraper';
import shouldRenderAddPaymentCard from '@libs/shouldRenderAppPaymentCard';
import {ReactionListContext} from '@pages/home/ReportScreenContext';
import AttachmentModalContext from '@pages/media/AttachmentModalScreen/AttachmentModalContext';
import variables from '@styles/variables';
import {openPersonalBankAccountSetupView} from '@userActions/BankAccounts';
import {hideEmojiPicker, isActive} from '@userActions/EmojiPickerAction';
Expand Down Expand Up @@ -181,7 +182,6 @@ import ReportActionItemMessage from './ReportActionItemMessage';
import ReportActionItemMessageEdit from './ReportActionItemMessageEdit';
import ReportActionItemSingle from './ReportActionItemSingle';
import ReportActionItemThread from './ReportActionItemThread';
import ReportAttachmentsContext from './ReportAttachmentsContext';
import TripSummary from './TripSummary';

type PureReportActionItemProps = {
Expand Down Expand Up @@ -442,7 +442,7 @@ function PureReportActionItem({
const [isHidden, setIsHidden] = useState(false);
const [moderationDecision, setModerationDecision] = useState<OnyxTypes.DecisionName>(CONST.MODERATION.MODERATOR_DECISION_APPROVED);
const reactionListRef = useContext(ReactionListContext);
const {updateHiddenAttachments} = useContext(ReportAttachmentsContext);
const {updateHiddenAttachments} = useContext(AttachmentModalContext);
const composerTextInputRef = useRef<TextInput | HTMLTextAreaElement>(null);
const popoverAnchorRef = useRef<Exclude<ContextMenuAnchor, TextInput>>(null);
const downloadedPreviews = useRef<string[]>([]);
Expand Down
115 changes: 0 additions & 115 deletions src/pages/home/report/ReportAttachments.tsx

This file was deleted.

Loading
Loading