Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
0d7c42c
refactor(contextmenu): consolidate popover state into single object
roryabraham Feb 28, 2026
1d8a441
refactor(contextmenu): remove manual memoization from BaseReportActio…
roryabraham Feb 28, 2026
ed71a5b
refactor(contextmenu): extract ConfirmDeleteReportActionModal
roryabraham Feb 28, 2026
183c3ea
feat(contextmenu): hoist MiniReportActionContextMenu to singleton
roryabraham Feb 28, 2026
ced51fe
refactor(contextmenu): delegate shouldKeepOpen to provider for mini mode
roryabraham Feb 28, 2026
826f62e
feat(contextmenu): hide mini menu on scroll
roryabraham Feb 28, 2026
2d2fbc5
refactor(contextmenu): add composition infrastructure
roryabraham Feb 28, 2026
183b120
refactor(contextmenu): wire composition architecture into Base
roryabraham Feb 28, 2026
e3e49ff
chore(contextmenu): polish and reduce lint warning budget
roryabraham Feb 28, 2026
8f65354
fix(contextmenu): restore hideDeleteModal to close global modal
roryabraham Feb 28, 2026
d3c8682
fix(contextmenu): resolve delete action from source report collection
roryabraham Feb 28, 2026
57af1e8
perf(contextmenu): add dependency array to mini-menu position effect
roryabraham Feb 28, 2026
c05ac51
fix(contextmenu): pass actionSourceReportID through showDeleteModal
roryabraham Feb 28, 2026
f264fc4
fix(contextmenu): hide mini-menu immediately on scroll
roryabraham Feb 28, 2026
3d7bbd3
fix(contextmenu): pass mini visible actions as disabled in overflow
roryabraham Feb 28, 2026
825eeb1
fix(contextmenu): add interceptAnonymousUser guard to non-anonymous a…
roryabraham Feb 28, 2026
4eb4e8d
docs(contextmenu): restore JSDoc comments on BaseReportActionContextM…
roryabraham Feb 28, 2026
47132bd
refactor(contextmenu): eliminate ContextMenuVisibilityContext
roryabraham Feb 28, 2026
20c362a
refactor(contextmenu): inline ContextMenuLayout into BaseReportAction…
roryabraham Feb 28, 2026
03373f3
refactor(contextmenu): derive disabledActionIDs internally
roryabraham Feb 28, 2026
3e2a6d6
refactor(contextmenu): derive 5 report props internally
roryabraham Feb 28, 2026
907634c
refactor(contextmenu): eliminate isMini via composition
roryabraham Mar 1, 2026
1a28b54
fix(lint): resolve ESLint and Prettier CI failures
roryabraham Mar 2, 2026
edb3720
refactor(contextmenu): inline content components, one component per file
roryabraham Mar 2, 2026
c49a546
rename BaseMiniContextMenuItem to MiniContextMenuItem
roryabraham Mar 2, 2026
16975a0
refactor(contextmenu): decompose into factory functions and type-spec…
roryabraham Mar 3, 2026
4881f5c
refactor(contextmenu): eliminate god object params from action factories
roryabraham Mar 3, 2026
9560020
chore: remove dead code from context menu refactor
roryabraham Mar 3, 2026
c953db4
refactor: remove ContextMenuAction barrel file
roryabraham Mar 3, 2026
56e85ee
refactor(contextmenu): eliminate centralized shouldShow config
roryabraham Mar 3, 2026
77a7302
refactor: remove unnecessary eslint-disable suppressions
roryabraham Mar 3, 2026
62643ac
refactor: make MiniReportActionContextMenu React Compiler compatible
roryabraham Mar 3, 2026
e3a45dc
refactor: fix PopoverContextMenu React Compiler and composition issues
roryabraham Mar 3, 2026
d8613ec
fix: replace dynamic import with static import in PopoverContextMenu
roryabraham Mar 3, 2026
03a155f
Reorganize ContextMenu directory structure
roryabraham Mar 3, 2026
b8fda9e
Destructure useMiniContextMenuState into individual fields in MiniRep…
roryabraham Mar 3, 2026
57dc808
Remove redundant isDelayButtonStateComplete props (default is already…
roryabraham Mar 3, 2026
d3e8e46
Consolidate interceptAnonymousUser: use @libs version, remove param f…
roryabraham Mar 3, 2026
0b0b86e
Inline useReportContextMenuData into PopoverReportContent
roryabraham Mar 3, 2026
6671d64
Flatten PopoverContextMenu subdirectories and move shared hook
roryabraham Mar 3, 2026
a88626f
Remove interceptAnonymousUser param from remaining action factories
roryabraham Mar 3, 2026
858f615
Delete unused copy action factory files
roryabraham Mar 3, 2026
597c37c
Remove redundant ancestorsRef in ConfirmDeleteReportActionModal
roryabraham Mar 4, 2026
6bc97c5
Extract originalReportID to avoid duplicate getOriginalReportID calls
roryabraham Mar 4, 2026
2d5edf5
Move actionTypes exports into actionConfig and delete actionTypes.ts
roryabraham Mar 4, 2026
ba5745b
Replace menuState prop with specific props in context menu content co…
roryabraham Mar 4, 2026
604fe38
Remove useMemo from PopoverReportActionContent for React Compiler
roryabraham Mar 4, 2026
18e7b3a
Refactor context menus to use visibleActions array pattern
roryabraham Mar 4, 2026
7244203
Remove unused isChronosReport prop from PureReportActionItem
roryabraham Mar 4, 2026
8de8157
Add JSDoc comments to MiniContextMenuProvider, actionConfig, and useR…
roryabraham Mar 4, 2026
12119fb
Context menu: destructure hook data, remove unused fields, optimize s…
roryabraham Mar 4, 2026
d046575
Fix jsx-a11y mouse-events-have-key-events; use relative imports
roryabraham Mar 4, 2026
3cc3e3b
Merge origin/main into rory-contextmenu-perf
roryabraham Mar 4, 2026
87e6a1a
chore: reduce lint warning budget from 353 to 334
roryabraham Mar 4, 2026
24fa4b5
fix: resolve CI failures (lint, prettier, test)
roryabraham Mar 4, 2026
7cf6141
fix: add sentryLabel to PreRenderer PressableWithoutFeedback
roryabraham Mar 4, 2026
ec1227f
refactor: use @gorhom/portal for MiniReportActionContextMenu
roryabraham Mar 4, 2026
726a2a7
fix: keep MiniReportActionContextMenu visible during scroll
roryabraham Mar 4, 2026
0b212ee
Restore main-branch MiniReportActionContextMenu scroll behavior
roryabraham Mar 4, 2026
d8da674
Remove hide timer from MiniContextMenuProvider
roryabraham Mar 4, 2026
67715c1
Fix six MiniReportActionContextMenu UI regressions
roryabraham Mar 5, 2026
b8a0cee
Merge origin/main into rory-contextmenu-perf
roryabraham Mar 6, 2026
1157955
Port main's ContextMenuActions changes to decomposed action files
roryabraham Mar 6, 2026
ad9e7e2
Fix merge: remove isArchivedNonExpenseReport from context menu consumers
roryabraham Mar 6, 2026
bdee918
Merge remote-tracking branch 'origin/main' into rory-contextmenu-perf
roryabraham Mar 6, 2026
19f5451
Fix hover flash regressions in MiniReportActionContextMenu
roryabraham Mar 7, 2026
531a5a8
Move ref cleanup from useEffect into performHide handler
roryabraham Mar 7, 2026
c0eabbf
Remove unnecessary double type assertions in test
roryabraham Mar 7, 2026
9111027
Restore accidentally removed comment in ReportScreen
roryabraham Mar 7, 2026
f4a6a64
Merge branch 'main' into rory-contextmenu-perf
roryabraham Mar 7, 2026
32477cf
Explode PopoverContextMenuState into individual useState variables
roryabraham Mar 9, 2026
ccb3895
Merge remote-tracking branch 'origin/main' into rory-contextmenu-perf
roryabraham Mar 9, 2026
b081731
Fix pretter
roryabraham Mar 10, 2026
97ce290
Merge origin/main into rory-contextmenu-perf
roryabraham Mar 12, 2026
e06611c
Port main's functional changes to decomposed action files
roryabraham Mar 12, 2026
78b7b62
refactor(contextmenu): convert action files to composition components
roryabraham Apr 6, 2026
50f126f
Merge remote-tracking branch 'origin/main' into rory-contextmenu-perf
roryabraham Apr 6, 2026
324c0a9
Port main's functional changes to decomposed action files
roryabraham Apr 6, 2026
2aedc8f
refactor(contextmenu): rename action files to PascalCase and split mu…
roryabraham Apr 6, 2026
e94e948
fix(contextmenu): hide mini context menu on scroll
roryabraham Apr 6, 2026
ec93c03
fix(contextmenu): hide mini on popover open and restore when popover …
roryabraham Apr 6, 2026
946ac37
Merge remote-tracking branch 'origin/main' into rory-contextmenu-perf
roryabraham Apr 7, 2026
ff2b1eb
Merge remote-tracking branch 'origin/main' into rory-contextmenu-perf
roryabraham Apr 8, 2026
f50d465
fix(contextmenu): show Mark as Unread in report-level menus without r…
roryabraham Apr 8, 2026
6867fe7
fix(contextmenu): address Codex review comments
roryabraham Apr 8, 2026
b7ee8df
fix(contextmenu): fix lint and typecheck for optional reportAction in…
roryabraham Apr 9, 2026
897fa05
Prettier
roryabraham Apr 9, 2026
54f3dc8
fix: add missing React import to ConfirmDeleteReportActionModal
roryabraham Apr 15, 2026
6d8d365
fix(contextmenu): hide mini menu when navigating via Reply in Thread
roryabraham Apr 15, 2026
a6a9c53
Merge remote-tracking branch 'origin/main' into rory-contextmenu-perf
roryabraham Apr 15, 2026
166a79d
fix(contextmenu): use callback ref for reliable overlay measurement a…
roryabraham Apr 15, 2026
def4d76
fix(hoverable): detect cursor already over element on mount
roryabraham Apr 15, 2026
da6062d
fix(a11y): restore Tab focus from report action row to mini context menu
roryabraham Apr 15, 2026
5175392
Merge remote-tracking branch 'origin/main' into rory-contextmenu-perf
roryabraham Apr 16, 2026
21f4ed9
test(contextmenu): pin the ordering of popover context menu items
roryabraham Apr 16, 2026
6241333
fix(contextmenu): resolve lint and React Compiler compliance issues
roryabraham Apr 16, 2026
13c0844
fix(contextmenu): hide mini menu when cursor leaves without entering it
roryabraham Apr 16, 2026
db186da
fix(contextmenu): ignore scrolls originating inside the anchored row
roryabraham Apr 16, 2026
1cad108
fix(a11y): restore Tab/Shift+Tab focus bridge with Portal-mounted menu
roryabraham Apr 17, 2026
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: 4 additions & 0 deletions src/CONST/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8744,6 +8744,10 @@ const CONST = {
},
},

PORTAL_HOST_NAMES: {
CONTEXT_MENU: 'contextMenu',
},

SENTRY_LABEL: {
NAVIGATION_TAB_BAR: {
EXPENSIFY_LOGO: 'NavigationTabBar-ExpensifyLogo',
Expand Down
4 changes: 2 additions & 2 deletions src/GlobalModals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import ScreenShareRequestModal from './components/ScreenShareRequestModal';
import UpdateAppModal from './components/UpdateAppModal';
import * as EmojiPickerAction from './libs/actions/EmojiPickerAction';
import {growlRef} from './libs/Growl';
import PopoverReportActionContextMenu from './pages/inbox/report/ContextMenu/PopoverReportActionContextMenu';
import PopoverContextMenu from './pages/inbox/report/ContextMenu/PopoverContextMenu';
import * as ReportActionContextMenu from './pages/inbox/report/ContextMenu/ReportActionContextMenu';

/**
Expand All @@ -21,7 +21,7 @@ function GlobalModals() {
<GrowlNotification ref={growlRef} />
<DelegateNoAccessModalProvider>
{/* eslint-disable-next-line react-hooks/refs -- module-level createRef, safe to pass as ref prop */}
<PopoverReportActionContextMenu ref={ReportActionContextMenu.contextMenuRef} />
<PopoverContextMenu ref={ReportActionContextMenu.contextMenuRef} />
</DelegateNoAccessModalProvider>
{/* eslint-disable-next-line react-hooks/refs -- module-level createRef, safe to pass as ref prop */}
<EmojiPicker ref={EmojiPickerAction.emojiPickerRef} />
Expand Down
35 changes: 2 additions & 33 deletions src/components/ContextMenuItem.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import React from 'react';
import type {GestureResponderEvent, StyleProp, View, ViewStyle} from 'react-native';
import type {GestureResponderEvent, StyleProp, ViewStyle} from 'react-native';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import useThrottledButtonState from '@hooks/useThrottledButtonState';
import useWindowDimensions from '@hooks/useWindowDimensions';
import getButtonState from '@libs/getButtonState';
import type IconAsset from '@src/types/utils/IconAsset';
import type WithSentryLabel from '@src/types/utils/SentryLabel';
import BaseMiniContextMenuItem from './BaseMiniContextMenuItem';
import FocusableMenuItem from './FocusableMenuItem';
import Icon from './Icon';

type ContextMenuItemProps = WithSentryLabel & {
/** Icon Component */
Expand All @@ -24,9 +21,6 @@ type ContextMenuItemProps = WithSentryLabel & {
/** Text to show when interaction was successful */
successText?: string;

/** Whether to show the mini menu */
isMini?: boolean;

/** Callback to fire when the item is pressed */
onPress: (event?: GestureResponderEvent | MouseEvent | KeyboardEvent) => void;

Expand All @@ -45,11 +39,6 @@ type ContextMenuItemProps = WithSentryLabel & {
/** Styles to apply to MenuItem wrapper */
wrapperStyle?: StyleProp<ViewStyle>;

shouldPreventDefaultFocusOnPress?: boolean;

/** The ref of mini context menu item */
buttonRef?: React.RefObject<View | null>;

/** Handles what to do when the item is focused */
onFocus?: () => void;

Expand All @@ -69,14 +58,11 @@ function ContextMenuItem({
successText = '',
icon,
text,
isMini = false,
description = '',
isAnonymousAction = false,
isFocused = false,
shouldLimitWidth = true,
wrapperStyle,
shouldPreventDefaultFocusOnPress = true,
buttonRef = {current: null},
onFocus = () => {},
onBlur = () => {},
disabled = false,
Expand Down Expand Up @@ -104,24 +90,7 @@ function ContextMenuItem({
const itemIcon = !isThrottledButtonActive && successIcon ? successIcon : icon;
const itemText = !isThrottledButtonActive && successText ? successText : text;

return isMini ? (
<BaseMiniContextMenuItem
ref={buttonRef}
tooltipText={itemText}
onPress={triggerPressAndUpdateSuccess}
isDelayButtonStateComplete={!isThrottledButtonActive}
shouldPreventDefaultFocusOnPress={shouldPreventDefaultFocusOnPress}
sentryLabel={sentryLabel}
>
{({hovered, pressed}) => (
<Icon
small
src={itemIcon}
fill={StyleUtils.getIconFillColor(getButtonState(hovered, pressed, !isThrottledButtonActive))}
/>
)}
</BaseMiniContextMenuItem>
) : (
return (
<FocusableMenuItem
title={itemText}
icon={itemIcon}
Expand Down
7 changes: 7 additions & 0 deletions src/components/Hoverable/ActiveHoverable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ function ActiveHoverable({onHoverIn, onHoverOut, shouldHandleScroll, isFocused =
setIsHovered(false);
}, [isFocused]);

useEffect(() => {
if (!elementRef.current?.matches(':hover') || isHoveredRef.current || isVisibilityHidden.current) {
return;
}
updateIsHovered(true);
}, [updateIsHovered]);

const handleMouseEvents = useCallback(
(type: 'enter' | 'leave') => () => {
if (shouldFreezeCapture) {
Expand Down
2 changes: 0 additions & 2 deletions src/components/LHNOptionsList/OptionRowLHN.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,6 @@ function OptionRowLHN({
report: {
reportID,
originalReportID: reportID,
isPinnedChat: optionItem.isPinned,
isUnreadChat: !!optionItem.isUnread,
},
reportAction: {
reportActionID: '-1',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@ import type {PressableStateCallbackType} from 'react-native';
import {View} from 'react-native';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import useThrottledButtonState from '@hooks/useThrottledButtonState';
import DomUtils from '@libs/DomUtils';
import getButtonState from '@libs/getButtonState';
import ReportActionComposeFocusManager from '@libs/ReportActionComposeFocusManager';
import variables from '@styles/variables';
import CONST from '@src/CONST';
import type IconAsset from '@src/types/utils/IconAsset';
import type WithSentryLabel from '@src/types/utils/SentryLabel';
import Icon from './Icon';
import type {PressableRef} from './Pressable/GenericPressable/types';
import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback';
import Tooltip from './Tooltip/PopoverAnchorTooltip';

type BaseMiniContextMenuItemProps = WithSentryLabel & {
type MiniContextMenuItemProps = WithSentryLabel & {
/**
* Text to display when hovering the menu item
*/
Expand All @@ -25,14 +28,33 @@ type BaseMiniContextMenuItemProps = WithSentryLabel & {
onPress: () => void;

/**
* The children to display within the menu item
* The children to display within the menu item.
* Used when custom rendering is needed (e.g. overflow button).
* Mutually exclusive with `icon`.
*/
children: React.ReactNode | ((state: PressableStateCallbackType) => React.ReactNode);
children?: React.ReactNode | ((state: PressableStateCallbackType) => React.ReactNode);

/**
* Icon to display. When provided, the component renders an Icon internally
* instead of using children.
*/
icon?: IconAsset;

/**
* Icon to show after a successful press. Requires `icon` to be set.
* When provided, the component manages a throttled success state internally.
*/
successIcon?: IconAsset;

/**
* Tooltip text to show during the success state.
*/
successTooltipText?: string;

/**
* Whether the button should be in the active state
*/
isDelayButtonStateComplete: boolean;
isDelayButtonStateComplete?: boolean;
/**
* Can be used to control the click event, and for example whether or not to lose focus from the composer when pressing the item
*/
Expand All @@ -48,25 +70,45 @@ type BaseMiniContextMenuItemProps = WithSentryLabel & {
* Component that renders a mini context menu item with a
* pressable. Also renders a tooltip when hovering the item.
*/
function BaseMiniContextMenuItem({
function MiniContextMenuItem({
tooltipText,
onPress,
children,
icon,
successIcon,
successTooltipText,
isDelayButtonStateComplete = true,
shouldPreventDefaultFocusOnPress = true,
ref,
sentryLabel,
}: BaseMiniContextMenuItemProps) {
}: MiniContextMenuItemProps) {
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
const [isThrottledButtonActive, setThrottledButtonInactive] = useThrottledButtonState();

const showSuccessState = !!successIcon && !isThrottledButtonActive;
const displayIcon = showSuccessState ? successIcon : icon;
const displayTooltip = showSuccessState && successTooltipText ? successTooltipText : tooltipText;
const isComplete = showSuccessState || isDelayButtonStateComplete;

const handlePress = () => {
if (successIcon && !isThrottledButtonActive) {
return;
}
onPress();
if (successIcon) {
setThrottledButtonInactive();
}
};

return (
<Tooltip
text={tooltipText}
text={displayTooltip}
shouldRender
>
<PressableWithoutFeedback
ref={ref}
onPress={onPress}
onPress={icon ? handlePress : onPress}
onMouseDown={(event) => {
if (!ReportActionComposeFocusManager.isFocused() && !ReportActionComposeFocusManager.isEditFocused()) {
const activeElement = DomUtils.getActiveElement();
Expand All @@ -86,23 +128,30 @@ function BaseMiniContextMenuItem({
event.preventDefault();
}
}}
accessibilityLabel={tooltipText}
accessibilityLabel={displayTooltip}
role={CONST.ROLE.BUTTON}
sentryLabel={sentryLabel}
style={({hovered, pressed}) => [
styles.reportActionContextMenuMiniButton,
StyleUtils.getButtonBackgroundColorStyle(getButtonState(hovered, pressed, isDelayButtonStateComplete), true),
isDelayButtonStateComplete && styles.cursorDefault,
StyleUtils.getButtonBackgroundColorStyle(getButtonState(hovered, pressed, isComplete), true),
isComplete && styles.cursorDefault,
]}
>
{(pressableState) => (
<View style={[StyleUtils.getWidthAndHeightStyle(variables.iconSizeNormal), styles.alignItemsCenter, styles.justifyContentCenter]}>
{typeof children === 'function' ? children(pressableState) : children}
{!!displayIcon && (
<Icon
small
src={displayIcon}
fill={StyleUtils.getIconFillColor(getButtonState(pressableState.hovered, pressableState.pressed, showSuccessState))}
/>
)}
{!displayIcon && (typeof children === 'function' ? children(pressableState) : children)}
</View>
)}
</PressableWithoutFeedback>
</Tooltip>
);
}

export default BaseMiniContextMenuItem;
export default MiniContextMenuItem;
10 changes: 5 additions & 5 deletions src/components/Reactions/MiniQuickEmojiReactions.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, {useCallback, useRef} from 'react';
import {View} from 'react-native';
import type {Emoji} from '@assets/emojis/types';
import BaseMiniContextMenuItem from '@components/BaseMiniContextMenuItem';
import Icon from '@components/Icon';
import MiniContextMenuItem from '@components/MiniContextMenuItem';
import Text from '@components/Text';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
Expand Down Expand Up @@ -65,7 +65,7 @@ function MiniQuickEmojiReactions({reportAction, reportActionID, onEmojiSelected,
return (
<View style={styles.flexRow}>
{CONST.QUICK_REACTIONS.slice(0, 3).map((emoji: Emoji) => (
<BaseMiniContextMenuItem
<MiniContextMenuItem
key={emoji.name}
isDelayButtonStateComplete={false}
tooltipText={`:${getLocalizedEmojiName(emoji.name, preferredLocale)}:`}
Expand All @@ -78,9 +78,9 @@ function MiniQuickEmojiReactions({reportAction, reportActionID, onEmojiSelected,
>
{getPreferredEmojiCode(emoji, preferredSkinTone)}
</Text>
</BaseMiniContextMenuItem>
</MiniContextMenuItem>
))}
<BaseMiniContextMenuItem
<MiniContextMenuItem
ref={ref}
onPress={callFunctionIfActionIsAllowed(() => {
if (!emojiPickerRef.current?.isEmojiPickerVisible) {
Expand All @@ -101,7 +101,7 @@ function MiniQuickEmojiReactions({reportAction, reportActionID, onEmojiSelected,
fill={StyleUtils.getIconFillColor(getButtonState(hovered, pressed, false))}
/>
)}
</BaseMiniContextMenuItem>
</MiniContextMenuItem>
</View>
);
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/ShowContextMenuContext/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {createContext, useContext} from 'react';
// eslint-disable-next-line no-restricted-imports
import type {GestureResponderEvent} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import {canUseTouchScreen} from '@libs/DeviceCapabilities';
import {getOriginalReportID} from '@libs/ReportUtils';
import {showContextMenu} from '@pages/inbox/report/ContextMenu/ReportActionContextMenu';
import type {ContextMenuAnchor} from '@pages/inbox/report/ContextMenu/ReportActionContextMenu';
import CONST from '@src/CONST';
Expand Down Expand Up @@ -52,7 +52,7 @@ function showContextMenuForReport(
contextMenuAnchor: anchor,
report: {
reportID,
originalReportID: originalReportID ?? reportID,
originalReportID: originalReportID ?? (reportID ? getOriginalReportID(reportID, action, undefined) : undefined),
isArchivedRoom,
},
reportAction: {
Expand Down
2 changes: 1 addition & 1 deletion src/libs/API/parameters/MarkAsUnreadParams.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
type MarkAsUnreadParams = {
reportID: string;
lastReadTime: string;
reportActionID: string;
reportActionID?: string;
};

export default MarkAsUnreadParams;
4 changes: 2 additions & 2 deletions src/libs/actions/Report/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@
// map of reportID to all reportActions for that report
const allReportActions: OnyxCollection<ReportActions> = {};

Onyx.connect({

Check warning on line 384 in src/libs/actions/Report/index.ts

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.COLLECTION.REPORT_ACTIONS,
callback: (actions, key) => {
if (!key || !actions) {
Expand All @@ -393,7 +393,7 @@
});

let allReports: OnyxCollection<Report>;
Onyx.connect({

Check warning on line 396 in src/libs/actions/Report/index.ts

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.COLLECTION.REPORT,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -402,7 +402,7 @@
});

let allPersonalDetails: OnyxEntry<PersonalDetailsList> = {};
Onyx.connect({

Check warning on line 405 in src/libs/actions/Report/index.ts

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) => {
allPersonalDetails = value ?? {};
Expand All @@ -417,7 +417,7 @@
});

let onboarding: OnyxEntry<Onboarding>;
Onyx.connect({

Check warning on line 420 in src/libs/actions/Report/index.ts

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.NVP_ONBOARDING,
callback: (val) => {
if (Array.isArray(val)) {
Expand Down Expand Up @@ -2364,7 +2364,7 @@
/**
* Sets the last read time on a report
*/
function markCommentAsUnread(reportID: string | undefined, reportActions: OnyxEntry<ReportActions>, reportAction: ReportAction, currentUserAccountID: number) {
function markCommentAsUnread(reportID: string | undefined, reportActions: OnyxEntry<ReportActions>, reportAction: ReportAction | undefined, currentUserAccountID: number) {
if (!reportID) {
Log.warn('7339cd6c-3263-4f89-98e5-730f0be15784 Invalid report passed to MarkCommentAsUnread. Not calling the API because it wil fail.');
return;
Expand All @@ -2391,7 +2391,7 @@

// If no action created date is provided, use the last action's from other user
const actionCreationTime =
reportAction?.created || (latestReportActionFromOtherUsers?.created ?? getReportLastVisibleActionCreated(report, transactionThreadReport) ?? DateUtils.getDBTime(0));
reportAction?.created ?? latestReportActionFromOtherUsers?.created ?? getReportLastVisibleActionCreated(report, transactionThreadReport) ?? DateUtils.getDBTime(0);

// We subtract 1 millisecond so that the lastReadTime is updated to just before a given reportAction's created date
// For example, if we want to mark a report action with ID 100 and created date '2014-04-01 16:07:02.999' unread, we set the lastReadTime to '2014-04-01 16:07:02.998'
Expand Down
21 changes: 11 additions & 10 deletions src/libs/interceptAnonymousUser.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import * as Session from './actions/Session';
import {InteractionManager} from 'react-native';
import {hideContextMenu} from '@pages/inbox/report/ContextMenu/ReportActionContextMenu';
import {isAnonymousUser, signOutAndRedirectToSignIn} from './actions/Session';

/**
* Checks if user is anonymous. If true, shows the sign in modal, else,
* executes the callback.
*/
const interceptAnonymousUser = (callback: () => void) => {
const isAnonymousUser = Session.isAnonymousUser();
if (isAnonymousUser) {
Session.signOutAndRedirectToSignIn();
function interceptAnonymousUser(callback: () => void, isAnonymousAction = false) {
if (isAnonymousUser() && !isAnonymousAction) {
hideContextMenu(false);
// eslint-disable-next-line @typescript-eslint/no-deprecated
InteractionManager.runAfterInteractions(() => {
signOutAndRedirectToSignIn();
});
} else {
callback();
}
};
}

export default interceptAnonymousUser;
Loading
Loading