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
34 changes: 25 additions & 9 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1080,7 +1080,7 @@ function doesReportBelongToWorkspace(report: OnyxEntry<Report>, policyMemberAcco
/**
* Given an array of reports, return them filtered by a policyID and policyMemberAccountIDs.
*/
function filterReportsByPolicyIDAndMemberAccountIDs(reports: Report[], policyMemberAccountIDs: number[] = [], policyID?: string) {
function filterReportsByPolicyIDAndMemberAccountIDs(reports: Array<OnyxEntry<Report>>, policyMemberAccountIDs: number[] = [], policyID?: string) {
return reports.filter((report) => !!report && doesReportBelongToWorkspace(report, policyMemberAccountIDs, policyID));
}

Expand Down Expand Up @@ -1166,14 +1166,15 @@ function findLastAccessedReport(
reportMetadata: OnyxCollection<ReportMetadata> = {},
policyID?: string,
policyMemberAccountIDs: number[] = [],
excludeReportID?: string,
): OnyxEntry<Report> {
// If it's the user's first time using New Expensify, then they could either have:
// - just a Concierge report, if so we'll return that
// - their Concierge report, and a separate report that must have deeplinked them to the app before they created their account.
// If it's the latter, we'll use the deeplinked report over the Concierge report,
// since the Concierge report would be incorrectly selected over the deep-linked report in the logic below.

let reportsValues = Object.values(reports ?? {}) as Report[];
let reportsValues = Object.values(reports ?? {});

if (!!policyID || policyMemberAccountIDs.length > 0) {
reportsValues = filterReportsByPolicyIDAndMemberAccountIDs(reportsValues, policyMemberAccountIDs, policyID);
Expand All @@ -1189,13 +1190,28 @@ function findLastAccessedReport(
});
}

if (ignoreDomainRooms) {
// We allow public announce rooms, admins, and announce rooms through since we bypass the default rooms beta for them.
// Check where ReportUtils.findLastAccessedReport is called in MainDrawerNavigator.js for more context.
// Domain rooms are now the only type of default room that are on the defaultRooms beta.
sortedReports = sortedReports.filter(
(report) => !isDomainRoom(report) || getPolicyType(report, policies) === CONST.POLICY.TYPE.FREE || hasExpensifyGuidesEmails(Object.keys(report?.participants ?? {}).map(Number)),
);
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
const shouldFilter = excludeReportID || ignoreDomainRooms;
if (shouldFilter) {
sortedReports = sortedReports.filter((report) => {
if (excludeReportID && report?.reportID === excludeReportID) {
return false;
}

// We allow public announce rooms, admins, and announce rooms through since we bypass the default rooms beta for them.
// Check where ReportUtils.findLastAccessedReport is called in MainDrawerNavigator.js for more context.
// Domain rooms are now the only type of default room that are on the defaultRooms beta.
if (
ignoreDomainRooms &&
isDomainRoom(report) &&
getPolicyType(report, policies) !== CONST.POLICY.TYPE.FREE &&
!hasExpensifyGuidesEmails(Object.keys(report?.participants ?? {}).map(Number))
) {
return false;
}

return true;
});
}

if (isFirstTimeNewExpensifyUser) {
Expand Down
47 changes: 14 additions & 33 deletions src/libs/actions/Report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,7 @@ function openReport(
function navigateToAndOpenReport(
userLogins: string[],
shouldDismissModal = true,
actionType?: string,
reportName?: string,
avatarUri?: string,
avatarFile?: File | CustomRNImageManipulatorResult | undefined,
Expand Down Expand Up @@ -1001,7 +1002,7 @@ function navigateToAndOpenReport(
Navigation.dismissModalWithReport(report);
} else {
Navigation.navigateWithSwitchPolicyID({route: ROUTES.HOME});
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(report?.reportID ?? '-1'));
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(report?.reportID ?? '-1'), actionType);
}
}

Expand Down Expand Up @@ -2008,7 +2009,7 @@ function updateWriteCapabilityAndNavigate(report: Report, newValue: WriteCapabil
/**
* Navigates to the 1:1 report with Concierge
*/
function navigateToConciergeChat(shouldDismissModal = false, checkIfCurrentPageActive = () => true) {
function navigateToConciergeChat(shouldDismissModal = false, checkIfCurrentPageActive = () => true, actionType?: string) {
// If conciergeChatReportID contains a concierge report ID, we navigate to the concierge chat using the stored report ID.
// Otherwise, we would find the concierge chat and navigate to it.
if (!conciergeChatReportID) {
Expand All @@ -2019,12 +2020,12 @@ function navigateToConciergeChat(shouldDismissModal = false, checkIfCurrentPageA
if (!checkIfCurrentPageActive()) {
return;
}
navigateToAndOpenReport([CONST.EMAIL.CONCIERGE], shouldDismissModal);
navigateToAndOpenReport([CONST.EMAIL.CONCIERGE], shouldDismissModal, actionType);
});
} else if (shouldDismissModal) {
Navigation.dismissModal(conciergeChatReportID);
} else {
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(conciergeChatReportID));
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(conciergeChatReportID), actionType);
}
}

Expand Down Expand Up @@ -2564,40 +2565,20 @@ function getCurrentUserAccountID(): number {
}

function navigateToMostRecentReport(currentReport: OnyxEntry<Report>) {
const reportID = currentReport?.reportID;
const sortedReportsByLastRead = ReportUtils.sortReportsByLastRead(Object.values(allReports ?? {}) as Report[], reportMetadata);

// We want to filter out the current report, hidden reports and empty chats

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Filtering out the current report:
This is now part of findLastAccessedReport.

Filtering out hidden reports:
This is not needed. We should navigate to the recent report no matter its notification preference. I believe this was done initially as a workaround because after you leave a workspace room we just change its notification status and we wanted to avoid landing on the same report. This problem is solved by excluding the current report.

Filtering out empty reports:
This is also not needed. I believe this was done as workaround because it was possible that you land on a chat that you never visited before. This is no longer a problem since sortReportsByLastRead will filter such reports (reports that do not have lastReadTime field).

const filteredReportsByLastRead = sortedReportsByLastRead.filter(
(sortedReport) =>
sortedReport?.reportID !== reportID &&
sortedReport?.notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN &&
ReportUtils.shouldReportBeInOptionList({
report: sortedReport,
currentReportId: '',
isInFocusMode: false,
betas: [],
policies: {},
excludeEmptyChats: true,
doesReportHaveViolations: false,
includeSelfDM: true,
}),
);
const lastAccessedReportID = filteredReportsByLastRead.at(-1)?.reportID;
const isChatThread = ReportUtils.isChatThread(currentReport);
const lastAccessedReportID = ReportUtils.findLastAccessedReport(allReports, false, undefined, false, false, reportMetadata, undefined, [], currentReport?.reportID)?.reportID;

if (lastAccessedReportID) {
const lastAccessedReportRoute = ROUTES.REPORT_WITH_ID.getRoute(lastAccessedReportID ?? '-1');
Navigation.goBack(lastAccessedReportRoute);
} else {
const participantAccountIDs = PersonalDetailsUtils.getAccountIDsByLogins([CONST.EMAIL.CONCIERGE]);
const chat = ReportUtils.getChatByParticipants([...participantAccountIDs, currentUserAccountID]);
if (chat?.reportID) {
// If it is not a chat thread we should call Navigation.goBack to pop the current route first before navigating to Concierge.
if (!isChatThread) {
Navigation.goBack();
}
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(chat?.reportID), CONST.NAVIGATION.TYPE.UP);
const isChatThread = ReportUtils.isChatThread(currentReport);

// If it is not a chat thread we should call Navigation.goBack to pop the current route first before navigating to Concierge.
if (!isChatThread) {
Navigation.goBack();
}

navigateToConciergeChat(false, () => true, CONST.NAVIGATION.TYPE.UP);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/pages/NewChatConfirmPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ function NewChatConfirmPage({newGroupDraft, allPersonalDetails}: NewChatConfirmP
}

const logins: string[] = (newGroupDraft.participants ?? []).map((participant) => participant.login);
Report.navigateToAndOpenReport(logins, true, newGroupDraft.reportName ?? '', newGroupDraft.avatarUri ?? '', avatarFile, optimisticReportID.current, true);
Report.navigateToAndOpenReport(logins, true, undefined, newGroupDraft.reportName ?? '', newGroupDraft.avatarUri ?? '', avatarFile, optimisticReportID.current, true);
}, [newGroupDraft, avatarFile]);

const stashedLocalAvatarImage = newGroupDraft?.avatarUri;
Expand Down