Skip to content
Merged
4 changes: 2 additions & 2 deletions src/pages/inbox/ReportScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import useDeferNonEssentials from './hooks/useDeferNonEssentials';
import useFlushDeferredWriteOnFocus from './hooks/useFlushDeferredWriteOnFocus';
import LinkedActionNotFoundGuard from './LinkedActionNotFoundGuard';
import ReactionListWrapper from './ReactionListWrapper';
import ReportActionComposePlaceholder from './report/ReportActionCompose/ReportActionComposePlaceholder';
import ReportActionCompose from './report/ReportActionCompose/ReportActionCompose';
import {ReportActionEditMessageContextProvider, ReportScreenEditMessageProviderWithTransactionThread} from './report/ReportActionEditMessageContext';
import ReportFooter from './report/ReportFooter';
import useClearReportActionDraftsOnReportChange from './report/useClearReportActionDraftsOnReportChange';
Expand Down Expand Up @@ -148,7 +148,7 @@ function ReportScreen({route, navigation}: ReportScreenProps) {
testID="report-actions-view-wrapper"
>
<ReportActionsList />
{shouldDeferNonEssentials ? <ReportActionComposePlaceholder /> : <ReportFooter />}
{shouldDeferNonEssentials ? <ReportActionCompose.Placeholder /> : <ReportFooter />}
</View>
</ConciergeDraftProvider>
</AgentZeroStatusProvider>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import ComposerActionMenu from './ComposerActionMenu';
import {useComposerEditState} from './ComposerContext';
import ComposerEditingButtons from './ComposerEditingButtons';

function ComposerActionButton() {
const {isEditingInComposer} = useComposerEditState();

if (isEditingInComposer) {
return <ComposerEditingButtons />;
}
return <ComposerActionMenu />;
}

export default ComposerActionButton;
Comment on lines +1 to +14

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

App crashes immediately on start.
import React from 'react'; is missing on this file.

Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,8 @@ import AttachmentPickerWithMenuItems from './AttachmentPickerWithMenuItems';
import {useComposerActions, useComposerEditState, useComposerMeta, useComposerSendState, useComposerState} from './ComposerContext';
import useAttachmentPicker from './useAttachmentPicker';

type ComposerActionMenuProps = {
reportID: string;
};

function ComposerActionMenu({reportID}: ComposerActionMenuProps) {
function ComposerActionMenu() {
const {reportID} = useComposerState();
const currentUserPersonalDetails = useCurrentUserPersonalDetails();
const {isMenuVisible, isFullComposerAvailable} = useComposerState();
const {draftComment} = useComposerEditState();
Expand Down
9 changes: 3 additions & 6 deletions src/pages/inbox/report/ReportActionCompose/ComposerBox.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import React from 'react';
import type {PropsWithChildren} from 'react';
import {View} from 'react-native';
import useOnyx from '@hooks/useOnyx';
import useThemeStyles from '@hooks/useThemeStyles';
import ONYXKEYS from '@src/ONYXKEYS';
import {useComposerMeta, useComposerSendState, useComposerState} from './ComposerContext';

type ComposerBoxProps = {
reportID: string;
children: React.ReactNode;
};

function ComposerBox({reportID, children}: ComposerBoxProps) {
function ComposerBox({children}: PropsWithChildren) {
const {reportID} = useComposerState();
const styles = useThemeStyles();
const {isFocused} = useComposerState();
const {isExceedingMaxLength, isBlockedFromConcierge} = useComposerSendState();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import type {PropsWithChildren} from 'react';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import useOnyx from '@hooks/useOnyx';
import useThemeStyles from '@hooks/useThemeStyles';
import {getReportOfflinePendingActionAndErrors} from '@libs/ReportUtils';
import ONYXKEYS from '@src/ONYXKEYS';
import {useComposerState} from './ComposerContext';

function ComposerContainer({children}: PropsWithChildren) {
const {reportID} = useComposerState();
const styles = useThemeStyles();
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`);
const [isComposerFullSize = false] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_IS_COMPOSER_FULL_SIZE}${reportID}`);
const {reportPendingAction: pendingAction} = getReportOfflinePendingActionAndErrors(report);

return (
<OfflineWithFeedback
shouldDisableOpacity
pendingAction={pendingAction}
style={isComposerFullSize ? styles.chatItemFullComposeRow : {}}
contentContainerStyle={isComposerFullSize ? styles.flex1 : {}}
>
{children}
</OfflineWithFeedback>
);
}

export default ComposerContainer;
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type ComposerText = string;

// Warm — changes on interaction
type ComposerState = {
reportID: string;
isFocused: boolean;
isMenuVisible: boolean;
isFullComposerAvailable: boolean;
Expand Down Expand Up @@ -90,6 +91,7 @@ const noop = () => {};
const ComposerTextContext = createContext<ComposerText>('');

const defaultState: ComposerState = {
reportID: '',
isFocused: false,
isMenuVisible: false,
isFullComposerAvailable: false,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';
import OfflineIndicator from '@components/OfflineIndicator';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import ComposerExceededLength from './ComposerExceededLength';
import ComposerFooter from './ComposerFooter';
import ComposerTypingIndicator from './ComposerTypingIndicator';

function ComposerDefaultFooter() {
const styles = useThemeStyles();
const {shouldUseNarrowLayout} = useResponsiveLayout();

return (
<ComposerFooter>
{!shouldUseNarrowLayout && <OfflineIndicator containerStyles={[styles.chatItemComposeSecondaryRow]} />}
<ComposerTypingIndicator />
<ComposerExceededLength />
</ComposerFooter>
);
}

export default ComposerDefaultFooter;
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import type {PropsWithChildren} from 'react';
import DragAndDropConsumer from '@components/DragAndDrop/Consumer';
import DropZoneUI from '@components/DropZone/DropZoneUI';
import DualDropZone from '@components/DropZone/DualDropZone';
Expand All @@ -14,15 +15,11 @@ import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID';
import {getParentReport, isChatRoom, isGroupChat, isInvoiceReport, isReportApproved, isSettled, temporary_getMoneyRequestOptions} from '@libs/ReportUtils';
import {hasReceipt as hasReceiptTransactionUtils} from '@libs/TransactionUtils';
import ONYXKEYS from '@src/ONYXKEYS';
import {useComposerState} from './ComposerContext';
import useAttachmentPicker from './useAttachmentPicker';
import useReceiptDrop from './useReceiptDrop';
import useShouldAddOrReplaceReceipt from './useShouldAddOrReplaceReceipt';

type ComposerDropZoneProps = {
reportID: string;
children: React.ReactNode;
};

type RichDropZoneProps = {
reportID: string;
shouldAddOrReplaceReceipt: boolean;
Expand Down Expand Up @@ -110,7 +107,8 @@ function RichDropZone({reportID, shouldAddOrReplaceReceipt, transactionID, onAtt
);
}

function ComposerDropZone({reportID, children}: ComposerDropZoneProps) {
function ComposerDropZone({children}: PropsWithChildren) {
const {reportID} = useComposerState();
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`);
const {shouldAddOrReplaceReceipt, transactionID} = useShouldAddOrReplaceReceipt(reportID);
const {pickAttachments, PDFValidationComponent: AttachmentPDFValidation, ErrorModal: AttachmentErrorModal} = useAttachmentPicker(reportID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@ import React from 'react';
import {View} from 'react-native';
import useThemeStyles from '@hooks/useThemeStyles';
import CONST from '@src/CONST';
import {useComposerEditActions} from './ComposerContext';
import {useComposerEditActions, useComposerState} from './ComposerContext';
import ComposerExpandCollapseButton from './ComposerExpandCollapseButton';
import MessageEditCancelButton from './MessageEditCancelButton';

type ComposerEditingButtonsProps = {
/** The report ID */
reportID: string;
};

function ComposerEditingButtons({reportID}: ComposerEditingButtonsProps) {
function ComposerEditingButtons() {
const {reportID} = useComposerState();
const styles = useThemeStyles();

const {deleteDraft} = useComposerEditActions();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@ import {canUseTouchScreen} from '@libs/DeviceCapabilities';
import DomUtils from '@libs/DomUtils';
import {hideEmojiPicker, isActive as isActiveEmojiPickerAction} from '@userActions/EmojiPickerAction';
import CONST from '@src/CONST';
import {useComposerMeta, useComposerSendState} from './ComposerContext';
import {useComposerMeta, useComposerSendState, useComposerState} from './ComposerContext';

type ComposerEmojiPickerProps = {
reportID: string;
};

function ComposerEmojiPicker({reportID}: ComposerEmojiPickerProps) {
function ComposerEmojiPicker() {
const {reportID} = useComposerState();
const styles = useThemeStyles();

const {isMediumScreenWidth} = useResponsiveLayout();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import React from 'react';
import type {PropsWithChildren} from 'react';
import {View} from 'react-native';
import useNetwork from '@hooks/useNetwork';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';

type ComposerFooterProps = {
children: React.ReactNode;
};

function ComposerFooter({children}: ComposerFooterProps) {
function ComposerFooter({children}: PropsWithChildren) {
const styles = useThemeStyles();
// eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth
const {isSmallScreenWidth} = useResponsiveLayout();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,15 @@ import ComposerWithSuggestions from './ComposerWithSuggestions';
import useAttachmentPicker from './useAttachmentPicker';
import useComposerSubmit from './useComposerSubmit';

type ComposerInputProps = {
reportID: string;
};

const AI_PLACEHOLDER_KEYS = ['reportActionCompose.askConciergeToUpdate', 'reportActionCompose.askConciergeToCorrect', 'reportActionCompose.askConciergeForHelp'] as const;

function getRandomPlaceholder(translate: LocalizedTranslate): string {
const randomIndex = Math.floor(Math.random() * AI_PLACEHOLDER_KEYS.length);
return translate(AI_PLACEHOLDER_KEYS[randomIndex]);
}

function ComposerInput({reportID}: ComposerInputProps) {
function ComposerInput() {
const {reportID} = useComposerState();
const {translate, preferredLocale} = useLocalize();
const {isMenuVisible} = useComposerState();
const {isBlockedFromConcierge, debouncedCommentMaxLengthValidation} = useComposerSendState();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react';
import {View} from 'react-native';
import useOnyx from '@hooks/useOnyx';
import useThemeStyles from '@hooks/useThemeStyles';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ComposerActionButton from './ComposerActionButton';
import ComposerBox from './ComposerBox';
import ComposerContainer from './ComposerContainer';
import {useComposerState} from './ComposerContext';
import ComposerDropZone from './ComposerDropZone';
import ComposerEmojiPicker from './ComposerEmojiPicker';
import ComposerImportedState from './ComposerImportedState';
import ComposerInput from './ComposerInput';
import ComposerLocalTime from './ComposerLocalTime';
import ComposerSendButton from './ComposerSendButton';

function ComposerInputArea() {
const {reportID} = useComposerState();
const styles = useThemeStyles();
const [isComposerFullSize = false] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_IS_COMPOSER_FULL_SIZE}${reportID}`);

return (
<View
testID={CONST.COMPOSER.TEST_ID.REPORT_ACTION_COMPOSE}
style={[isComposerFullSize && styles.chatItemFullComposeRow]}
>
<ComposerLocalTime />
<View style={isComposerFullSize ? styles.flex1 : {}}>
<ComposerContainer>
<ComposerDropZone>
<ComposerBox>
<ComposerActionButton />
<ComposerInput />
<ComposerEmojiPicker />
<ComposerSendButton />
</ComposerBox>
</ComposerDropZone>
</ComposerContainer>
<ComposerImportedState />
</View>
</View>
);
}

export default ComposerInputArea;
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@ import {isAgentEmail} from '@libs/SessionUtils';
import ParticipantLocalTime from '@pages/inbox/report/ParticipantLocalTime';
import ONYXKEYS from '@src/ONYXKEYS';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import {useComposerState} from './ComposerContext';

type ComposerLocalTimeProps = {
reportID: string;
};

function ComposerLocalTime({reportID}: ComposerLocalTimeProps) {
function ComposerLocalTime() {
const {reportID} = useComposerState();
const [isComposerFullSize = false] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_IS_COMPOSER_FULL_SIZE}${reportID}`);
const currentUserPersonalDetails = useCurrentUserPersonalDetails();
const personalDetails = usePersonalDetails();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import CONST from '@src/CONST';
* chatItemComposeSecondaryRow, and icons [Plus, Emoji, Send].
* If the real composer changes its layout or icon set, update this placeholder to match.
*/
function ReportActionComposePlaceholder() {
function ComposerPlaceholder() {
const theme = useTheme();
const styles = useThemeStyles();
const {translate} = useLocalize();
Expand Down Expand Up @@ -86,4 +86,4 @@ function ReportActionComposePlaceholder() {
);
}

export default ReportActionComposePlaceholder;
export default ComposerPlaceholder;
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ function ComposerProvider({children, reportID}: ComposerProviderProps) {
};

const composerState = {
reportID,
isFocused,
isMenuVisible,
isFullComposerAvailable,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import useLocalize from '@hooks/useLocalize';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import CONST from '@src/CONST';
import {useComposerEditState, useComposerSendState} from './ComposerContext';
import {useComposerEditState, useComposerSendState, useComposerState} from './ComposerContext';
import SubmitDraftButton from './SubmitDraftButton';
import useComposerSubmit from './useComposerSubmit';

function ComposerSendButton({reportID}: {reportID: string}) {
function ComposerSendButton() {
const {reportID} = useComposerState();
const styles = useThemeStyles();
const {translate} = useLocalize();
const icons = useMemoizedLazyExpensifyIcons(['Send', 'Checkmark']);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import React from 'react';
import useShouldSuppressConciergeIndicators from '@hooks/useShouldSuppressConciergeIndicators';
import ReportTypingIndicator from '@pages/inbox/report/ReportTypingIndicator';
import {useComposerState} from './ComposerContext';

function AgentZeroAwareTypingIndicator({reportID}: {reportID: string}) {
function ComposerTypingIndicator() {
const {reportID} = useComposerState();
const shouldSuppress = useShouldSuppressConciergeIndicators(reportID);
if (shouldSuppress) {
return null;
}
return <ReportTypingIndicator reportID={reportID} />;
}

export default AgentZeroAwareTypingIndicator;
export default ComposerTypingIndicator;
Loading
Loading