Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TS migration] Migrate 'ContextMenu' and 'ShowContextMenuContext' components to TypeScript #33715

Merged
merged 32 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4081242
[TS migration] Migrate 'ShowContextMenuContext.js' component to TypeS…
blazejkustra Dec 11, 2023
7b67f02
Change ContextMenu extenstions
blazejkustra Dec 28, 2023
09c957d
Merge branch 'main' into ts/ContextMenu
blazejkustra Dec 28, 2023
44abb62
Migrate MiniReportActionContextMenu
blazejkustra Dec 28, 2023
84e77cd
Migrate ContextMenuActions
blazejkustra Dec 29, 2023
d36fb5b
Fix ContextMenuActions type errors
blazejkustra Dec 29, 2023
e395228
Improve ContextMenu types
blazejkustra Dec 29, 2023
460e7ef
Merge branch 'main' into ts/ContextMenu
blazejkustra Jan 2, 2024
7ae56a3
Fix almost all type errors
blazejkustra Jan 2, 2024
4e30106
Merge branch 'main' into ts/ContextMenu
blazejkustra Jan 5, 2024
795c387
Fix all typerrors
blazejkustra Jan 5, 2024
4ea9f87
Make childReportID default value string
blazejkustra Jan 5, 2024
b5421c5
Fix type imports
blazejkustra Jan 5, 2024
dd66071
Merge branch 'main' into ts/ContextMenu
blazejkustra Jan 8, 2024
e6dd4fc
Fix prettier
blazejkustra Jan 8, 2024
149eda4
Merge branch 'main' into ts/ContextMenu
blazejkustra Jan 9, 2024
92ea0ed
Adjust code after review
blazejkustra Jan 9, 2024
c410cb2
Adjust code after code review
blazejkustra Jan 10, 2024
a61bf91
Merge branch 'main' into ts/ContextMenu
blazejkustra Jan 11, 2024
ef6122a
Fix ts errors
blazejkustra Jan 11, 2024
6d8ef3b
Split ContextMenuAction into two
blazejkustra Jan 11, 2024
b887754
Merge branch 'main' into ts/ContextMenu
blazejkustra Jan 12, 2024
816ec3c
Merge branch 'main' into ts/ContextMenu
blazejkustra Jan 12, 2024
6d677fb
Fix typecheck
blazejkustra Jan 12, 2024
03eed43
Merge branch 'main' into ts/ContextMenu
blazejkustra Jan 15, 2024
945912c
Fix typecheck
blazejkustra Jan 15, 2024
67d7d73
Merge branch 'main' into ts/ContextMenu
blazejkustra Jan 16, 2024
db17b54
Add getPageCoords util
blazejkustra Jan 16, 2024
c4c560e
Rename function to extractPointerEvent
blazejkustra Jan 16, 2024
68a28c9
Merge branch 'main' into ts/ContextMenu
blazejkustra Jan 16, 2024
c5bb9be
Fix typecheck on main
blazejkustra Jan 16, 2024
0247630
Fix lint
blazejkustra Jan 16, 2024
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
3 changes: 1 addition & 2 deletions src/components/Modal/index.android.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import {AppState} from 'react-native';
import withWindowDimensions from '@components/withWindowDimensions';
import ComposerFocusManager from '@libs/ComposerFocusManager';
import BaseModal from './BaseModal';
import type BaseModalProps from './types';
Expand Down Expand Up @@ -28,4 +27,4 @@ function Modal({useNativeDriver = true, ...rest}: BaseModalProps) {
}

Modal.displayName = 'Modal';
export default withWindowDimensions(Modal);
export default Modal;
3 changes: 1 addition & 2 deletions src/components/Modal/index.ios.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import withWindowDimensions from '@components/withWindowDimensions';
import BaseModal from './BaseModal';
import type BaseModalProps from './types';

Expand All @@ -15,4 +14,4 @@ function Modal({children, ...rest}: BaseModalProps) {
}

Modal.displayName = 'Modal';
export default withWindowDimensions(Modal);
export default Modal;
3 changes: 1 addition & 2 deletions src/components/Modal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, {useState} from 'react';
import withWindowDimensions from '@components/withWindowDimensions';
import useStyleUtils from '@hooks/useStyleUtils';
import useTheme from '@hooks/useTheme';
import StatusBar from '@libs/StatusBar';
Expand Down Expand Up @@ -55,4 +54,4 @@ function Modal({fullscreen = true, onModalHide = () => {}, type, onModalShow = (
}

Modal.displayName = 'Modal';
export default withWindowDimensions(Modal);
export default Modal;
74 changes: 36 additions & 38 deletions src/components/Modal/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type {ViewStyle} from 'react-native';
import type {ModalProps} from 'react-native-modal';
import type {ValueOf} from 'type-fest';
import type {WindowDimensionsProps} from '@components/withWindowDimensions/types';
import type CONST from '@src/CONST';

type PopoverAnchorPosition = {
Expand All @@ -11,57 +10,56 @@ type PopoverAnchorPosition = {
left?: number;
};

type BaseModalProps = WindowDimensionsProps &
Partial<ModalProps> & {
/** Decides whether the modal should cover fullscreen. FullScreen modal has backdrop */
fullscreen?: boolean;
type BaseModalProps = Partial<ModalProps> & {
/** Decides whether the modal should cover fullscreen. FullScreen modal has backdrop */
fullscreen?: boolean;

/** Should we close modal on outside click */
shouldCloseOnOutsideClick?: boolean;
/** Should we close modal on outside click */
shouldCloseOnOutsideClick?: boolean;

/** Should we announce the Modal visibility changes? */
shouldSetModalVisibility?: boolean;
/** Should we announce the Modal visibility changes? */
shouldSetModalVisibility?: boolean;

/** Callback method fired when the user requests to close the modal */
onClose: (ref?: React.RefObject<HTMLElement>) => void;
/** Callback method fired when the user requests to close the modal */
onClose: () => void;

/** State that determines whether to display the modal or not */
isVisible: boolean;
/** State that determines whether to display the modal or not */
isVisible: boolean;

/** Callback method fired when the user requests to submit the modal content. */
onSubmit?: () => void;
/** Callback method fired when the user requests to submit the modal content. */
onSubmit?: () => void;

/** Callback method fired when the modal is hidden */
onModalHide?: () => void;
/** Callback method fired when the modal is hidden */
onModalHide?: () => void;

/** Callback method fired when the modal is shown */
onModalShow?: () => void;
/** Callback method fired when the modal is shown */
onModalShow?: () => void;

/** Style of modal to display */
type?: ValueOf<typeof CONST.MODAL.MODAL_TYPE>;
/** Style of modal to display */
type?: ValueOf<typeof CONST.MODAL.MODAL_TYPE>;

/** The anchor position of a popover modal. Has no effect on other modal types. */
popoverAnchorPosition?: PopoverAnchorPosition;
/** The anchor position of a popover modal. Has no effect on other modal types. */
popoverAnchorPosition?: PopoverAnchorPosition;

outerStyle?: ViewStyle;
outerStyle?: ViewStyle;

/** Whether the modal should go under the system statusbar */
statusBarTranslucent?: boolean;
/** Whether the modal should go under the system statusbar */
statusBarTranslucent?: boolean;

/** Whether the modal should avoid the keyboard */
avoidKeyboard?: boolean;
/** Whether the modal should avoid the keyboard */
avoidKeyboard?: boolean;

/** Modal container styles */
innerContainerStyle?: ViewStyle;
/** Modal container styles */
innerContainerStyle?: ViewStyle;

/**
* Whether the modal should hide its content while animating. On iOS, set to true
* if `useNativeDriver` is also true, to avoid flashes in the UI.
*
* See: https://github.com/react-native-modal/react-native-modal/pull/116
* */
hideModalContentWhileAnimating?: boolean;
};
/**
* Whether the modal should hide its content while animating. On iOS, set to true
* if `useNativeDriver` is also true, to avoid flashes in the UI.
*
* See: https://github.com/react-native-modal/react-native-modal/pull/116
* */
hideModalContentWhileAnimating?: boolean;
};

export default BaseModalProps;
export type {PopoverAnchorPosition};
2 changes: 1 addition & 1 deletion src/components/Popover/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type PopoverProps = BaseModalProps & {
anchorPosition?: PopoverAnchorPosition;

/** The anchor alignment of the popover */
anchorAlignment: AnchorAlignment;
anchorAlignment?: AnchorAlignment;

/** The anchor ref of the popover */
anchorRef: React.RefObject<HTMLElement>;
Expand Down
2 changes: 1 addition & 1 deletion src/components/PopoverWithoutOverlay/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function PopoverWithoutOverlay(
close: onClose,
anchorRef,
});
removeOnClose = Modal.setCloseModal(() => onClose(anchorRef));
removeOnClose = Modal.setCloseModal(() => onClose());
blazejkustra marked this conversation as resolved.
Show resolved Hide resolved
} else {
onModalHide();
close(anchorRef);
Expand Down
17 changes: 5 additions & 12 deletions src/components/Reactions/MiniQuickEmojiReactions.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, {useRef} from 'react';
import {View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import type {Emoji} from '@assets/emojis/types';
import BaseMiniContextMenuItem from '@components/BaseMiniContextMenuItem';
Expand All @@ -16,16 +15,7 @@ import * as EmojiPickerAction from '@userActions/EmojiPickerAction';
import * as Session from '@userActions/Session';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {ReportActionReactions} from '@src/types/onyx';
import type {BaseQuickEmojiReactionsProps} from './QuickEmojiReactions/types';

type MiniQuickEmojiReactionsOnyxProps = {
/** All the emoji reactions for the report action. */
emojiReactions: OnyxEntry<ReportActionReactions>;

/** The user's preferred skin tone. */
preferredSkinTone: OnyxEntry<string | number>;
};
import type {BaseQuickEmojiReactionsOnyxProps, BaseQuickEmojiReactionsProps} from './QuickEmojiReactions/types';

type MiniQuickEmojiReactionsProps = BaseQuickEmojiReactionsProps & {
/**
Expand Down Expand Up @@ -112,11 +102,14 @@ function MiniQuickEmojiReactions({

MiniQuickEmojiReactions.displayName = 'MiniQuickEmojiReactions';

export default withOnyx<MiniQuickEmojiReactionsProps, MiniQuickEmojiReactionsOnyxProps>({
export default withOnyx<MiniQuickEmojiReactionsProps, BaseQuickEmojiReactionsOnyxProps>({
preferredSkinTone: {
key: ONYXKEYS.PREFERRED_EMOJI_SKIN_TONE,
},
emojiReactions: {
key: ({reportActionID}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS}${reportActionID}`,
},
preferredLocale: {
key: ONYXKEYS.NVP_PREFERRED_LOCALE,
},
})(MiniQuickEmojiReactions);
28 changes: 15 additions & 13 deletions src/components/Reactions/QuickEmojiReactions/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,7 @@ type OpenPickerCallback = (element?: PickerRefElement, anchorOrigin?: AnchorOrig

type CloseContextMenuCallback = () => void;

type BaseQuickEmojiReactionsOnyxProps = {
/** All the emoji reactions for the report action. */
emojiReactions: OnyxEntry<ReportActionReactions>;

/** The user's preferred locale. */
preferredLocale: OnyxEntry<Locale>;

/** The user's preferred skin tone. */
preferredSkinTone: OnyxEntry<string | number>;
};

type BaseQuickEmojiReactionsProps = BaseQuickEmojiReactionsOnyxProps & {
type BaseReactionsProps = {
/** Callback to fire when an emoji is selected. */
onEmojiSelected: (emoji: Emoji, emojiReactions: OnyxEntry<ReportActionReactions>) => void;

Expand All @@ -45,7 +34,20 @@ type BaseQuickEmojiReactionsProps = BaseQuickEmojiReactionsOnyxProps & {
reportActionID: string;
};

type QuickEmojiReactionsProps = BaseQuickEmojiReactionsProps & {
type BaseQuickEmojiReactionsOnyxProps = {
/** All the emoji reactions for the report action. */
emojiReactions: OnyxEntry<ReportActionReactions>;

/** The user's preferred locale. */
preferredLocale: OnyxEntry<Locale>;

/** The user's preferred skin tone. */
preferredSkinTone: OnyxEntry<string | number>;
};

type BaseQuickEmojiReactionsProps = BaseReactionsProps & BaseQuickEmojiReactionsOnyxProps;

type QuickEmojiReactionsProps = BaseReactionsProps & {
/**
* Function that can be called to close the context menu
* in which this component is rendered.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React from 'react';
import type {GestureResponderEvent, Text as RNText} from 'react-native';
import * as DeviceCapabilities from '@libs/DeviceCapabilities';
import * as ReportUtils from '@libs/ReportUtils';
import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu';
import CONST from '@src/CONST';
import type ReportAction from '@src/types/onyx/ReportAction';

const ShowContextMenuContext = React.createContext({
blazejkustra marked this conversation as resolved.
Show resolved Hide resolved
anchor: null,
Expand All @@ -16,17 +18,25 @@ ShowContextMenuContext.displayName = 'ShowContextMenuContext';
/**
* Show the report action context menu.
*
* @param {Object} event - Press event object
* @param {Element} anchor - Context menu anchor
* @param {String} reportID - Active Report ID
* @param {Object} action - ReportAction for ContextMenu
* @param {Function} checkIfContextMenuActive Callback to update context menu active state
* @param {Boolean} [isArchivedRoom=false] - Is the report an archived room
* @param event - Press event object
* @param anchor - Context menu anchor
* @param reportID - Active Report ID
* @param action - ReportAction for ContextMenu
* @param checkIfContextMenuActive Callback to update context menu active state
* @param isArchivedRoom - Is the report an archived room
*/
function showContextMenuForReport(event, anchor, reportID, action, checkIfContextMenuActive, isArchivedRoom = false) {
function showContextMenuForReport(
event: GestureResponderEvent | MouseEvent,
anchor: RNText | null,
reportID: string,
action: ReportAction,
checkIfContextMenuActive: () => void,
isArchivedRoom = false,
) {
if (!DeviceCapabilities.canUseTouchScreen()) {
return;
}

ReportActionContextMenu.showContextMenu(
CONST.CONTEXT_MENU_TYPES.REPORT_ACTION,
event,
Expand Down
12 changes: 6 additions & 6 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4325,9 +4325,9 @@ function navigateToPrivateNotes(report: Report, session: Session) {
/**
* Checks if thread replies should be displayed
*/
function shouldDisplayThreadReplies(reportAction: ReportAction, reportID: string): boolean {
const hasReplies = (reportAction.childVisibleActionCount ?? 0) > 0;
return hasReplies && !!reportAction.childCommenterCount && !isThreadFirstChat(reportAction, reportID);
function shouldDisplayThreadReplies(reportAction: OnyxEntry<ReportAction>, reportID: string): boolean {
const hasReplies = (reportAction?.childVisibleActionCount ?? 0) > 0;
return hasReplies && !!reportAction?.childCommenterCount && !isThreadFirstChat(reportAction, reportID);
}

/**
Expand All @@ -4339,17 +4339,17 @@ function shouldDisplayThreadReplies(reportAction: ReportAction, reportID: string
* - The action is a whisper action and it's neither a report preview nor IOU action
* - The action is the thread's first chat
*/
function shouldDisableThread(reportAction: ReportAction, reportID: string) {
function shouldDisableThread(reportAction: OnyxEntry<ReportAction>, reportID: string) {
const isSplitBillAction = ReportActionsUtils.isSplitBillAction(reportAction);
const isDeletedAction = ReportActionsUtils.isDeletedAction(reportAction);
const isReportPreviewAction = ReportActionsUtils.isReportPreviewAction(reportAction);
const isIOUAction = ReportActionsUtils.isMoneyRequestAction(reportAction);
const isWhisperAction = ReportActionsUtils.isWhisperAction(reportAction);

return (
CONST.REPORT.ACTIONS.THREAD_DISABLED.some((action: string) => action === reportAction.actionName) ||
CONST.REPORT.ACTIONS.THREAD_DISABLED.some((action: string) => action === reportAction?.actionName) ||
isSplitBillAction ||
(isDeletedAction && !reportAction.childVisibleActionCount) ||
(isDeletedAction && !reportAction?.childVisibleActionCount) ||
(isWhisperAction && !isReportPreviewAction && !isIOUAction) ||
isThreadFirstChat(reportAction, reportID)
);
Expand Down
2 changes: 1 addition & 1 deletion src/libs/actions/IOU.js
Original file line number Diff line number Diff line change
Expand Up @@ -2447,7 +2447,7 @@ function updateMoneyRequestAmountAndCurrency(transactionID, transactionThreadRep
}

/**
* @param {String} transactionID
* @param {String | undefined} transactionID
* @param {Object} reportAction - the money request reportAction we are deleting
* @param {Boolean} isSingleTransactionView
*/
Expand Down
2 changes: 1 addition & 1 deletion src/libs/actions/Report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1986,7 +1986,7 @@ function toggleEmojiReaction(
reportID: string,
reportAction: ReportAction,
reactionObject: Emoji,
existingReactions: ReportActionReactions | undefined,
existingReactions: ReportActionReactions | null,
blazejkustra marked this conversation as resolved.
Show resolved Hide resolved
paramSkinTone: number = preferredSkinTone,
) {
const originalReportID = ReportUtils.getOriginalReportID(reportID, reportAction);
Expand Down
Loading
Loading