diff --git a/src/CONST.ts b/src/CONST.ts index 0fa1c64be44..f4c7ecb5215 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -59,6 +59,9 @@ const cardActiveStates: number[] = [2, 3, 4, 7]; const CONST = { MERGED_ACCOUNT_PREFIX: 'MERGED_', DEFAULT_POLICY_ROOM_CHAT_TYPES: [chatTypes.POLICY_ADMINS, chatTypes.POLICY_ANNOUNCE, chatTypes.DOMAIN_ALL], + + // Note: Group and Self-DM excluded as these are not tied to a Workspace + WORKSPACE_ROOM_TYPES: [chatTypes.POLICY_ADMINS, chatTypes.POLICY_ANNOUNCE, chatTypes.DOMAIN_ALL, chatTypes.POLICY_ROOM, chatTypes.POLICY_EXPENSE_CHAT], ANDROID_PACKAGE_NAME, ANIMATED_TRANSITION: 300, ANIMATED_TRANSITION_FROM_VALUE: 100, diff --git a/src/components/RoomHeaderAvatars.tsx b/src/components/RoomHeaderAvatars.tsx index 9298062aa6f..c23108adc0e 100644 --- a/src/components/RoomHeaderAvatars.tsx +++ b/src/components/RoomHeaderAvatars.tsx @@ -13,10 +13,15 @@ import Text from './Text'; type RoomHeaderAvatarsProps = { icons: Icon[]; reportID: string; + isGroupChat?: boolean; }; -function RoomHeaderAvatars({icons, reportID}: RoomHeaderAvatarsProps) { +function RoomHeaderAvatars({icons, reportID, isGroupChat}: RoomHeaderAvatarsProps) { const navigateToAvatarPage = (icon: Icon) => { + if (isGroupChat) { + return; + } + if (icon.type === CONST.ICON_TYPE_WORKSPACE) { Navigation.navigate(ROUTES.REPORT_AVATAR.getRoute(reportID)); return; diff --git a/src/libs/API/parameters/StartSplitBillParams.ts b/src/libs/API/parameters/StartSplitBillParams.ts index 30d21697ac6..623f291eb69 100644 --- a/src/libs/API/parameters/StartSplitBillParams.ts +++ b/src/libs/API/parameters/StartSplitBillParams.ts @@ -12,6 +12,7 @@ type StartSplitBillParams = { isFromGroupDM: boolean; createdReportActionID?: string; billable: boolean; + chatType?: string; }; export default StartSplitBillParams; diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 9fa28535a7a..a2bf892b96b 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1193,7 +1193,8 @@ function hasOnlyTransactionsWithPendingRoutes(iouReportID: string | undefined): * If the report is a thread and has a chat type set, it is a workspace chat. */ function isWorkspaceThread(report: OnyxEntry): boolean { - return isThread(report) && isChatReport(report) && !!getChatType(report); + const chatType = getChatType(report); + return isThread(report) && isChatReport(report) && CONST.WORKSPACE_ROOM_TYPES.some((type) => chatType === type); } /** diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 8582e9e3f3d..39630eca80a 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -2248,6 +2248,50 @@ function trackExpense( Report.notifyNewAction(activeReportID, payeeAccountID); } +function getOrCreateOptimisticSplitChatReport(existingSplitChatReportID: string, participants: Participant[], participantAccountIDs: number[], currentUserAccountID: number) { + // The existing chat report could be passed as reportID or exist on the sole "participant" (in this case a report option) + const existingChatReportID = existingSplitChatReportID || participants[0].reportID; + + // Check if the report is available locally if we do have one + let existingSplitChatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${existingChatReportID}`]; + + // If we do not have one locally then we will search for a chat with the same participants (only for 1:1 chats). + const shouldGetOrCreateOneOneDM = participants.length < 2; + if (!existingSplitChatReport && shouldGetOrCreateOneOneDM) { + existingSplitChatReport = ReportUtils.getChatByParticipants(participantAccountIDs); + } + + // We found an existing chat report we are done... + if (existingSplitChatReport) { + // Yes, these are the same, but give the caller a way to identify if we created a new report or not + return {existingSplitChatReport, splitChatReport: existingSplitChatReport}; + } + + // No existing chat by this point we need to create it + const allParticipantsAccountIDs = [...participantAccountIDs, currentUserAccountID]; + + // Create a Group Chat if we have multiple participants + if (participants.length > 1) { + const splitChatReport = ReportUtils.buildOptimisticChatReport( + allParticipantsAccountIDs, + '', + CONST.REPORT.CHAT_TYPE.GROUP, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, + ); + return {existingSplitChatReport: null, splitChatReport}; + } + + // Otherwise, create a new 1:1 chat report + const splitChatReport = ReportUtils.buildOptimisticChatReport(allParticipantsAccountIDs); + return {existingSplitChatReport: null, splitChatReport}; +} + /** * Build the Onyx data and IOU split necessary for splitting a bill with 3+ users. * 1. Build the optimistic Onyx data for the group chat, i.e. chatReport and iouReportAction creating the former if it doesn't yet exist. @@ -2280,31 +2324,7 @@ function createSplitsAndOnyxData( const currentUserEmailForIOUSplit = PhoneNumber.addSMSDomainIfPhoneNumber(currentUserLogin); const participantAccountIDs = participants.map((participant) => Number(participant.accountID)); - const existingChatReportID = existingSplitChatReportID || participants[0].reportID; - let existingSplitChatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${existingChatReportID}`]; - if (!existingSplitChatReport) { - existingSplitChatReport = participants.length < 2 ? ReportUtils.getChatByParticipants(participantAccountIDs) : null; - } - let newChat: ReportUtils.OptimisticChatReport | EmptyObject = {}; - const allParticipantsAccountIDs = [...participantAccountIDs, currentUserAccountID]; - if (!existingSplitChatReport && participants.length > 1) { - newChat = ReportUtils.buildOptimisticChatReport( - allParticipantsAccountIDs, - '', - CONST.REPORT.CHAT_TYPE.GROUP, - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, - ); - } - if (isEmptyObject(newChat)) { - newChat = ReportUtils.buildOptimisticChatReport(allParticipantsAccountIDs); - } - const splitChatReport = existingSplitChatReport ?? newChat; + const {splitChatReport, existingSplitChatReport} = getOrCreateOptimisticSplitChatReport(existingSplitChatReportID, participants, participantAccountIDs, currentUserAccountID); const isOwnPolicyExpenseChat = !!splitChatReport.isOwnPolicyExpenseChat; const splitTransaction = TransactionUtils.buildOptimisticTransaction( @@ -2785,11 +2805,7 @@ function startSplitBill( ) { const currentUserEmailForIOUSplit = PhoneNumber.addSMSDomainIfPhoneNumber(currentUserLogin); const participantAccountIDs = participants.map((participant) => Number(participant.accountID)); - const existingSplitChatReport = - existingSplitChatReportID || participants[0].reportID - ? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${existingSplitChatReportID || participants[0].reportID}`] - : ReportUtils.getChatByParticipants(participantAccountIDs); - const splitChatReport = existingSplitChatReport ?? ReportUtils.buildOptimisticChatReport(participantAccountIDs); + const {splitChatReport, existingSplitChatReport} = getOrCreateOptimisticSplitChatReport(existingSplitChatReportID, participants, participantAccountIDs, currentUserAccountID); const isOwnPolicyExpenseChat = !!splitChatReport.isOwnPolicyExpenseChat; const {name: filename, source, state = CONST.IOU.RECEIPT_STATE.SCANREADY} = receipt; @@ -3047,6 +3063,7 @@ function startSplitBill( isFromGroupDM: !existingSplitChatReport, billable, ...(existingSplitChatReport ? {} : {createdReportActionID: splitChatCreatedReportAction.reportActionID}), + chatType: splitChatReport?.chatType, }; API.write(WRITE_COMMANDS.START_SPLIT_BILL, parameters, {optimisticData, successData, failureData}); diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index f06b40af885..9093bf32b9d 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -218,6 +218,7 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD )}