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

[CP Staging] Fix Split Scan flow for Group Chats #39276

Merged
merged 14 commits into from
Apr 1, 2024
3 changes: 3 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
7 changes: 6 additions & 1 deletion src/components/RoomHeaderAvatars.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/libs/API/parameters/StartSplitBillParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type StartSplitBillParams = {
isFromGroupDM: boolean;
createdReportActionID?: string;
billable: boolean;
chatType?: string;
};

export default StartSplitBillParams;
3 changes: 2 additions & 1 deletion src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<Report>): 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);
}

/**
Expand Down
77 changes: 47 additions & 30 deletions src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2248,6 +2248,50 @@ function trackExpense(
Report.notifyNewAction(activeReportID, payeeAccountID);
}

function getOrCreateOptimisticSplitChatReport(existingSplitChatReportID: string, participants: Participant[], participantAccountIDs: number[], currentUserAccountID: number) {
hayata-suenaga marked this conversation as resolved.
Show resolved Hide resolved
// 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);
Copy link
Contributor

Choose a reason for hiding this comment

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

Here we weren't checking if a group chat already existed so we were creating a new group chat every time when splitting a bill with the same users (#40579) we fixed this in #42444

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure how this is supposed to behave. You can create multiple groups with the same users. If you create a split which of those existing group should be used?

cc @marcaaron

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Creating a new group is the expected behavior. The issue you linked is incorrect.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

FAB flows always create a new group now.

}

// 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.
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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});
Expand Down
1 change: 1 addition & 0 deletions src/pages/ReportDetailsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
<RoomHeaderAvatars
icons={icons}
reportID={report?.reportID}
isGroupChat={ReportUtils.isGroupChat(report)}
/>
)}
</View>
Expand Down
Loading