Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 10 additions & 2 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ const ROUTES = {
SEARCH_ADVANCED_FILTERS_POSTED: 'search/filters/posted',
SEARCH_REPORT: {
route: 'search/view/:reportID/:reportActionID?',
getRoute: ({reportID, reportActionID, backTo}: {reportID: string; reportActionID?: string; backTo?: string}) => {
getRoute: ({reportID, reportActionID, backTo}: {reportID: string | undefined; reportActionID?: string; backTo?: string}) => {
if (!reportID) {
Log.warn('Invalid reportID is used to build the SEARCH_REPORT route');
}
const baseRoute = reportActionID ? (`search/view/${reportID}/${reportActionID}` as const) : (`search/view/${reportID}` as const);
return getUrlWithBackToParam(baseRoute, backTo);
},
Expand Down Expand Up @@ -341,7 +344,12 @@ const ROUTES = {
},
REPORT_WITH_ID_DETAILS_SHARE_CODE: {
route: 'r/:reportID/details/shareCode',
getRoute: (reportID: string, backTo?: string) => getUrlWithBackToParam(`r/${reportID}/details/shareCode` as const, backTo),
getRoute: (reportID: string | undefined, backTo?: string) => {
if (!reportID) {
Log.warn('Invalid reportID is used to build the REPORT_WITH_ID_DETAILS_SHARE_CODE route');
}
return getUrlWithBackToParam(`r/${reportID}/details/shareCode` as const, backTo);
},
},
ATTACHMENTS: {
route: 'attachment',
Expand Down
4 changes: 2 additions & 2 deletions src/components/MenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import getButtonState from '@libs/getButtonState';
import Parser from '@libs/Parser';
import type {AvatarSource} from '@libs/UserUtils';
import variables from '@styles/variables';
import {checkIfActionIsAllowed} from '@userActions/Session';
import {callFunctionIfActionIsAllowed} from '@userActions/Session';
import CONST from '@src/CONST';
import type {Icon as IconType} from '@src/types/onyx/OnyxCommon';
import type {TooltipAnchorAlignment} from '@src/types/utils/AnchorAlignment';
Expand Down Expand Up @@ -611,7 +611,7 @@ function MenuItem(
<Hoverable>
{(isHovered) => (
<PressableWithSecondaryInteraction
onPress={shouldCheckActionAllowedOnPress ? checkIfActionIsAllowed(onPressAction, isAnonymousAction) : onPressAction}
onPress={shouldCheckActionAllowedOnPress ? callFunctionIfActionIsAllowed(onPressAction, isAnonymousAction) : onPressAction}
onPressIn={() => shouldBlockSelection && shouldUseNarrowLayout && canUseTouchScreen() && ControlSelection.block()}
onPressOut={ControlSelection.unblock}
onSecondaryInteraction={onSecondaryInteraction}
Expand Down
6 changes: 3 additions & 3 deletions src/components/PinButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import React from 'react';
import useLocalize from '@hooks/useLocalize';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import * as ReportActions from '@userActions/Report';
import * as Session from '@userActions/Session';
import {togglePinnedState} from '@userActions/Report';
import {callFunctionIfActionIsAllowed} from '@userActions/Session';
import CONST from '@src/CONST';
import type {Report} from '@src/types/onyx';
import Icon from './Icon';
Expand All @@ -24,7 +24,7 @@ function PinButton({report}: PinButtonProps) {
return (
<Tooltip text={report.isPinned ? translate('common.unPin') : translate('common.pin')}>
<PressableWithFeedback
onPress={Session.checkIfActionIsAllowed(() => ReportActions.togglePinnedState(report.reportID, report.isPinned ?? false))}
onPress={callFunctionIfActionIsAllowed(() => togglePinnedState(report.reportID, report.isPinned ?? false))}
style={styles.touchableButtonImage}
accessibilityLabel={report.isPinned ? translate('common.unPin') : translate('common.pin')}
role={CONST.ROLE.BUTTON}
Expand Down
34 changes: 17 additions & 17 deletions src/components/PromotedActionsBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import type {StyleProp, ViewStyle} from 'react-native';
import {View} from 'react-native';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import * as HeaderUtils from '@libs/HeaderUtils';
import * as Localize from '@libs/Localize';
import {getPinMenuItem, getShareMenuItem} from '@libs/HeaderUtils';
import {translateLocal} from '@libs/Localize';
import getTopmostCentralPaneRoute from '@libs/Navigation/getTopmostCentralPaneRoute';
import Navigation, {navigationRef} from '@libs/Navigation/Navigation';
import type {RootStackParamList, State} from '@libs/Navigation/types';
import * as ReportUtils from '@libs/ReportUtils';
import * as ReportActions from '@userActions/Report';
import * as Session from '@userActions/Session';
import {changeMoneyRequestHoldStatus} from '@libs/ReportUtils';
import {joinRoom, navigateToAndOpenReport, navigateToAndOpenReportWithAccountIDs} from '@userActions/Report';
import {callFunctionIfActionIsAllowed} from '@userActions/Session';
import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
import SCREENS from '@src/SCREENS';
Expand Down Expand Up @@ -44,25 +44,25 @@ type PromotedActionsType = Record<BasePromotedActions, (report: OnyxReport) => P
const PromotedActions = {
pin: (report) => ({
key: CONST.PROMOTED_ACTIONS.PIN,
...HeaderUtils.getPinMenuItem(report),
...getPinMenuItem(report),
}),
share: (report, backTo) => ({
key: CONST.PROMOTED_ACTIONS.SHARE,
...HeaderUtils.getShareMenuItem(report, backTo),
...getShareMenuItem(report, backTo),
}),
join: (report) => ({
key: CONST.PROMOTED_ACTIONS.JOIN,
icon: Expensicons.ChatBubbles,
text: Localize.translateLocal('common.join'),
onSelected: Session.checkIfActionIsAllowed(() => {
text: translateLocal('common.join'),
onSelected: callFunctionIfActionIsAllowed(() => {
Navigation.dismissModal();
ReportActions.joinRoom(report);
joinRoom(report);
}),
}),
message: ({reportID, accountID, login}) => ({
key: CONST.PROMOTED_ACTIONS.MESSAGE,
icon: Expensicons.CommentBubbles,
text: Localize.translateLocal('common.message'),
text: translateLocal('common.message'),
onSelected: () => {
if (reportID) {
Navigation.dismissModal(reportID);
Expand All @@ -71,18 +71,18 @@ const PromotedActions = {

// The accountID might be optimistic, so we should use the login if we have it
if (login) {
ReportActions.navigateToAndOpenReport([login]);
navigateToAndOpenReport([login]);
return;
}
if (accountID) {
ReportActions.navigateToAndOpenReportWithAccountIDs([accountID]);
navigateToAndOpenReportWithAccountIDs([accountID]);
}
},
}),
hold: ({isTextHold, reportAction, reportID, isDelegateAccessRestricted, setIsNoDelegateAccessMenuVisible, currentSearchHash}) => ({
key: CONST.PROMOTED_ACTIONS.HOLD,
icon: Expensicons.Stopwatch,
text: Localize.translateLocal(`iou.${isTextHold ? 'hold' : 'unhold'}`),
text: translateLocal(`iou.${isTextHold ? 'hold' : 'unhold'}`),
onSelected: () => {
if (isDelegateAccessRestricted) {
setIsNoDelegateAccessMenuVisible(true); // Show the menu
Expand All @@ -92,15 +92,15 @@ const PromotedActions = {
if (!isTextHold) {
Navigation.goBack();
}
const targetedReportID = reportID ?? reportAction?.childReportID ?? '';
const targetedReportID = reportID ?? reportAction?.childReportID;
const topmostCentralPaneRoute = getTopmostCentralPaneRoute(navigationRef.getRootState() as State<RootStackParamList>);

if (topmostCentralPaneRoute?.name !== SCREENS.SEARCH.CENTRAL_PANE && isTextHold) {
ReportUtils.changeMoneyRequestHoldStatus(reportAction, ROUTES.REPORT_WITH_ID.getRoute(targetedReportID));
changeMoneyRequestHoldStatus(reportAction, ROUTES.REPORT_WITH_ID.getRoute(targetedReportID));
return;
}

ReportUtils.changeMoneyRequestHoldStatus(reportAction, ROUTES.SEARCH_REPORT.getRoute({reportID: targetedReportID}), currentSearchHash);
changeMoneyRequestHoldStatus(reportAction, ROUTES.SEARCH_REPORT.getRoute({reportID: targetedReportID}), currentSearchHash);
},
}),
} satisfies PromotedActionsType;
Expand Down
14 changes: 7 additions & 7 deletions src/components/Reactions/AddReactionBubble.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import getButtonState from '@libs/getButtonState';
import variables from '@styles/variables';
import * as EmojiPickerAction from '@userActions/EmojiPickerAction';
import {emojiPickerRef, resetEmojiPopoverAnchor, showEmojiPicker} from '@userActions/EmojiPickerAction';
import type {AnchorOrigin} from '@userActions/EmojiPickerAction';
import * as Session from '@userActions/Session';
import {callFunctionIfActionIsAllowed} from '@userActions/Session';
import CONST from '@src/CONST';
import type {ReportAction} from '@src/types/onyx';
import type {CloseContextMenuCallback, OpenPickerCallback, PickerRefElement} from './QuickEmojiReactions/types';
Expand Down Expand Up @@ -54,11 +54,11 @@ function AddReactionBubble({onSelectEmoji, reportAction, onPressOpenPicker, onWi
const ref = useRef<View | HTMLDivElement>(null);
const {translate} = useLocalize();

useEffect(() => EmojiPickerAction.resetEmojiPopoverAnchor, []);
useEffect(() => resetEmojiPopoverAnchor, []);

const onPress = () => {
const openPicker = (refParam?: PickerRefElement, anchorOrigin?: AnchorOrigin) => {
EmojiPickerAction.showEmojiPicker(
showEmojiPicker(
() => {
setIsEmojiPickerActive?.(false);
},
Expand All @@ -72,7 +72,7 @@ function AddReactionBubble({onSelectEmoji, reportAction, onPressOpenPicker, onWi
);
};

if (!EmojiPickerAction.emojiPickerRef.current?.isEmojiPickerVisible) {
if (!emojiPickerRef.current?.isEmojiPickerVisible) {
setIsEmojiPickerActive?.(true);
if (onPressOpenPicker) {
onPressOpenPicker(openPicker);
Expand All @@ -81,7 +81,7 @@ function AddReactionBubble({onSelectEmoji, reportAction, onPressOpenPicker, onWi
}
} else {
setIsEmojiPickerActive?.(false);
EmojiPickerAction.emojiPickerRef.current.hideEmojiPicker();
emojiPickerRef.current.hideEmojiPicker();
}
};

Expand All @@ -90,7 +90,7 @@ function AddReactionBubble({onSelectEmoji, reportAction, onPressOpenPicker, onWi
<PressableWithFeedback
ref={ref}
style={({hovered, pressed}) => [styles.emojiReactionBubble, styles.userSelectNone, StyleUtils.getEmojiReactionBubbleStyle(hovered || pressed, false, isContextMenu)]}
onPress={Session.checkIfActionIsAllowed(onPress)}
onPress={callFunctionIfActionIsAllowed(onPress)}
onMouseDown={(event) => {
// Allow text input blur when Add reaction is right clicked
if (!event || event.button === 2) {
Expand Down
49 changes: 17 additions & 32 deletions src/components/Reactions/MiniQuickEmojiReactions.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, {useRef} from 'react';
import {View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import {useOnyx} from 'react-native-onyx';
import type {Emoji} from '@assets/emojis/types';
import BaseMiniContextMenuItem from '@components/BaseMiniContextMenuItem';
import Icon from '@components/Icon';
Expand All @@ -9,14 +9,14 @@ import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import * as EmojiUtils from '@libs/EmojiUtils';
import {getLocalizedEmojiName, getPreferredEmojiCode} from '@libs/EmojiUtils';
import getButtonState from '@libs/getButtonState';
import variables from '@styles/variables';
import * as EmojiPickerAction from '@userActions/EmojiPickerAction';
import * as Session from '@userActions/Session';
import {emojiPickerRef, showEmojiPicker} from '@userActions/EmojiPickerAction';
import {callFunctionIfActionIsAllowed} from '@userActions/Session';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {BaseQuickEmojiReactionsOnyxProps, BaseQuickEmojiReactionsProps} from './QuickEmojiReactions/types';
import type {BaseQuickEmojiReactionsProps} from './QuickEmojiReactions/types';

type MiniQuickEmojiReactionsProps = BaseQuickEmojiReactionsProps & {
/**
Expand All @@ -32,23 +32,18 @@ type MiniQuickEmojiReactionsProps = BaseQuickEmojiReactionsProps & {
* context menu which we just show on web, when hovering
* a message.
*/
function MiniQuickEmojiReactions({
reportAction,
onEmojiSelected,
preferredLocale = CONST.LOCALES.DEFAULT,
preferredSkinTone = CONST.EMOJI_DEFAULT_SKIN_TONE,
emojiReactions = {},
onPressOpenPicker = () => {},
onEmojiPickerClosed = () => {},
}: MiniQuickEmojiReactionsProps) {
function MiniQuickEmojiReactions({reportAction, reportActionID, onEmojiSelected, onPressOpenPicker = () => {}, onEmojiPickerClosed = () => {}}: MiniQuickEmojiReactionsProps) {
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
const ref = useRef<View>(null);
const {translate} = useLocalize();
const [preferredLocale] = useOnyx(ONYXKEYS.NVP_PREFERRED_LOCALE, {initialValue: CONST.LOCALES.DEFAULT});
const [preferredSkinTone] = useOnyx(ONYXKEYS.PREFERRED_EMOJI_SKIN_TONE, {initialValue: CONST.EMOJI_DEFAULT_SKIN_TONE});
const [emojiReactions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS}${reportActionID}`, {initialValue: {}});

const openEmojiPicker = () => {
onPressOpenPicker();
EmojiPickerAction.showEmojiPicker(
showEmojiPicker(
onEmojiPickerClosed,
(emojiCode, emojiObject) => {
onEmojiSelected(emojiObject, emojiReactions);
Expand All @@ -66,24 +61,24 @@ function MiniQuickEmojiReactions({
<BaseMiniContextMenuItem
key={emoji.name}
isDelayButtonStateComplete={false}
tooltipText={`:${EmojiUtils.getLocalizedEmojiName(emoji.name, preferredLocale)}:`}
onPress={Session.checkIfActionIsAllowed(() => onEmojiSelected(emoji, emojiReactions))}
tooltipText={`:${getLocalizedEmojiName(emoji.name, preferredLocale)}:`}
onPress={callFunctionIfActionIsAllowed(() => onEmojiSelected(emoji, emojiReactions))}
>
<Text
style={[styles.miniQuickEmojiReactionText, styles.userSelectNone]}
dataSet={{[CONST.SELECTION_SCRAPER_HIDDEN_ELEMENT]: true}}
>
{EmojiUtils.getPreferredEmojiCode(emoji, preferredSkinTone)}
{getPreferredEmojiCode(emoji, preferredSkinTone)}
</Text>
</BaseMiniContextMenuItem>
))}
<BaseMiniContextMenuItem
ref={ref}
onPress={Session.checkIfActionIsAllowed(() => {
if (!EmojiPickerAction.emojiPickerRef.current?.isEmojiPickerVisible) {
onPress={callFunctionIfActionIsAllowed(() => {
if (!emojiPickerRef.current?.isEmojiPickerVisible) {
openEmojiPicker();
} else {
EmojiPickerAction.emojiPickerRef.current?.hideEmojiPicker();
emojiPickerRef.current?.hideEmojiPicker();
}
})}
isDelayButtonStateComplete={false}
Expand All @@ -104,14 +99,4 @@ function MiniQuickEmojiReactions({

MiniQuickEmojiReactions.displayName = 'MiniQuickEmojiReactions';

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);
export default MiniQuickEmojiReactions;
Original file line number Diff line number Diff line change
@@ -1,41 +1,42 @@
import React from 'react';
import {View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import {useOnyx} from 'react-native-onyx';
import type {Emoji} from '@assets/emojis/types';
import AddReactionBubble from '@components/Reactions/AddReactionBubble';
import EmojiReactionBubble from '@components/Reactions/EmojiReactionBubble';
import Tooltip from '@components/Tooltip';
import useThemeStyles from '@hooks/useThemeStyles';
import * as EmojiUtils from '@libs/EmojiUtils';
import * as Session from '@userActions/Session';
import {getLocalizedEmojiName, getPreferredEmojiCode} from '@libs/EmojiUtils';
import {callFunctionIfActionIsAllowed} from '@userActions/Session';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {BaseQuickEmojiReactionsOnyxProps, BaseQuickEmojiReactionsProps} from './types';
import type {BaseQuickEmojiReactionsProps} from './types';

function BaseQuickEmojiReactions({
reportAction,
reportActionID,
onEmojiSelected,
preferredLocale = CONST.LOCALES.DEFAULT,
preferredSkinTone = CONST.EMOJI_DEFAULT_SKIN_TONE,
emojiReactions = {},
onPressOpenPicker = () => {},
onWillShowPicker = () => {},
setIsEmojiPickerActive,
}: BaseQuickEmojiReactionsProps) {
const styles = useThemeStyles();
const [preferredLocale] = useOnyx(ONYXKEYS.NVP_PREFERRED_LOCALE, {initialValue: CONST.LOCALES.DEFAULT});
const [preferredSkinTone] = useOnyx(ONYXKEYS.PREFERRED_EMOJI_SKIN_TONE, {initialValue: CONST.EMOJI_DEFAULT_SKIN_TONE});
const [emojiReactions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS}${reportActionID}`, {initialValue: {}});

return (
<View style={styles.quickReactionsContainer}>
{CONST.QUICK_REACTIONS.map((emoji: Emoji) => (
<Tooltip
text={`:${EmojiUtils.getLocalizedEmojiName(emoji.name, preferredLocale)}:`}
text={`:${getLocalizedEmojiName(emoji.name, preferredLocale)}:`}
key={emoji.name}
>
<View>
<EmojiReactionBubble
emojiCodes={[EmojiUtils.getPreferredEmojiCode(emoji, preferredSkinTone)]}
emojiCodes={[getPreferredEmojiCode(emoji, preferredSkinTone)]}
isContextMenu
onPress={Session.checkIfActionIsAllowed(() => onEmojiSelected(emoji, emojiReactions))}
onPress={callFunctionIfActionIsAllowed(() => onEmojiSelected(emoji, emojiReactions))}
/>
</View>
</Tooltip>
Expand All @@ -54,14 +55,4 @@ function BaseQuickEmojiReactions({

BaseQuickEmojiReactions.displayName = 'BaseQuickEmojiReactions';

export default withOnyx<BaseQuickEmojiReactionsProps, BaseQuickEmojiReactionsOnyxProps>({
preferredSkinTone: {
key: ONYXKEYS.PREFERRED_EMOJI_SKIN_TONE,
},
emojiReactions: {
key: ({reportActionID}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS}${reportActionID}`,
},
preferredLocale: {
key: ONYXKEYS.NVP_PREFERRED_LOCALE,
},
})(BaseQuickEmojiReactions);
export default BaseQuickEmojiReactions;
Loading