diff --git a/src/CONST.ts b/src/CONST.ts
index 1489df5c051a..9ed2903941b6 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -691,6 +691,7 @@ const CONST = {
DOMAIN_ALL: 'domainAll',
POLICY_ROOM: 'policyRoom',
POLICY_EXPENSE_CHAT: 'policyExpenseChat',
+ SELF_DM: 'selfDM',
},
WORKSPACE_CHAT_ROOMS: {
ANNOUNCE: '#announce',
diff --git a/src/components/ReportWelcomeText.tsx b/src/components/ReportWelcomeText.tsx
index 6ade416e82ca..e9bbd0f27bdc 100644
--- a/src/components/ReportWelcomeText.tsx
+++ b/src/components/ReportWelcomeText.tsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, {useMemo} from 'react';
import {View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
@@ -35,7 +35,8 @@ function ReportWelcomeText({report, policy, personalDetails}: ReportWelcomeTextP
const styles = useThemeStyles();
const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(report);
const isChatRoom = ReportUtils.isChatRoom(report);
- const isDefault = !(isChatRoom || isPolicyExpenseChat);
+ const isSelfDM = ReportUtils.isSelfDM(report);
+ const isDefault = !(isChatRoom || isPolicyExpenseChat || isSelfDM);
const participantAccountIDs = report?.participantAccountIDs ?? [];
const isMultipleParticipant = participantAccountIDs.length > 1;
const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs(participantAccountIDs, personalDetails), isMultipleParticipant);
@@ -44,6 +45,7 @@ function ReportWelcomeText({report, policy, personalDetails}: ReportWelcomeTextP
const moneyRequestOptions = ReportUtils.getMoneyRequestOptions(report, policy, participantAccountIDs);
const additionalText = moneyRequestOptions.map((item) => translate(`reportActionsView.iouTypes.${item}`)).join(', ');
const canEditPolicyDescription = ReportUtils.canEditPolicyDescription(policy);
+ const reportName = ReportUtils.getReportName(report);
const navigateToReport = () => {
if (!report?.reportID) {
@@ -53,12 +55,22 @@ function ReportWelcomeText({report, policy, personalDetails}: ReportWelcomeTextP
Navigation.navigate(ROUTES.REPORT_WITH_ID_DETAILS.getRoute(report.reportID));
};
+ const welcomeHeroText = useMemo(() => {
+ if (isChatRoom) {
+ return translate('reportActionsView.welcomeToRoom', {roomName: reportName});
+ }
+
+ if (isSelfDM) {
+ return translate('reportActionsView.yourSpace');
+ }
+
+ return translate('reportActionsView.sayHello');
+ }, [isChatRoom, isSelfDM, translate, reportName]);
+
return (
<>
-
- {isChatRoom ? translate('reportActionsView.welcomeToRoom', {roomName: ReportUtils.getReportName(report)}) : translate('reportActionsView.sayHello')}
-
+ {welcomeHeroText}
{isPolicyExpenseChat &&
@@ -114,6 +126,11 @@ function ReportWelcomeText({report, policy, personalDetails}: ReportWelcomeTextP
{roomWelcomeMessage.phrase2 !== undefined && {roomWelcomeMessage.phrase2}}
))}
+ {isSelfDM && (
+
+ {translate('reportActionsView.beginningOfChatHistorySelfDM')}
+
+ )}
{isDefault && (
{translate('reportActionsView.beginningOfChatHistory')}
diff --git a/src/languages/en.ts b/src/languages/en.ts
index 2a0139c64c07..bd57843e9245 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -492,8 +492,10 @@ export default {
beginningOfChatHistoryPolicyExpenseChatPartOne: 'Collaboration between ',
beginningOfChatHistoryPolicyExpenseChatPartTwo: ' and ',
beginningOfChatHistoryPolicyExpenseChatPartThree: ' starts here! 🎉 This is the place to chat, request money and settle up.',
+ beginningOfChatHistorySelfDM: 'This is your personal space. Use it for notes, tasks, drafts, and reminders.',
chatWithAccountManager: 'Chat with your account manager here',
sayHello: 'Say hello!',
+ yourSpace: 'Your space',
welcomeToRoom: ({roomName}: WelcomeToRoomParams) => `Welcome to ${roomName}!`,
usePlusButton: ({additionalText}: UsePlusButtonParams) => `\nYou can also use the + button to ${additionalText}, or assign a task!`,
iouTypes: {
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 20f4cf8aeac8..83ed2ca1c89c 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -485,8 +485,10 @@ export default {
beginningOfChatHistoryPolicyExpenseChatPartOne: '¡La colaboración entre ',
beginningOfChatHistoryPolicyExpenseChatPartTwo: ' y ',
beginningOfChatHistoryPolicyExpenseChatPartThree: ' empieza aquí! 🎉 Este es el lugar donde chatear, pedir dinero y pagar.',
+ beginningOfChatHistorySelfDM: 'Este es tu espacio personal. Úsalo para notas, tareas, borradores y recordatorios.',
chatWithAccountManager: 'Chatea con tu gestor de cuenta aquí',
sayHello: '¡Saluda!',
+ yourSpace: 'Tu espacio',
welcomeToRoom: ({roomName}: WelcomeToRoomParams) => `¡Bienvenido a ${roomName}!`,
usePlusButton: ({additionalText}: UsePlusButtonParams) => `\n¡También puedes usar el botón + de abajo para ${additionalText}, o asignar una tarea!`,
iouTypes: {
diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts
index 342006eca710..706263774b01 100644
--- a/src/libs/OptionsListUtils.ts
+++ b/src/libs/OptionsListUtils.ts
@@ -114,6 +114,7 @@ type GetOptionsConfig = {
includeMultipleParticipantReports?: boolean;
includePersonalDetails?: boolean;
includeRecentReports?: boolean;
+ includeSelfDM?: boolean;
sortByReportTypeInSearch?: boolean;
searchInputValue?: string;
showChatPreviewLine?: boolean;
@@ -675,6 +676,8 @@ function createOption(
result.tooltipText = ReportUtils.getReportParticipantsTitle(report.visibleChatMemberAccountIDs ?? []);
result.isWaitingOnBankAccount = report.isWaitingOnBankAccount;
result.policyID = report.policyID;
+ result.isSelfDM = ReportUtils.isSelfDM(report);
+
hasMultipleParticipants = personalDetailList.length > 1 || result.isChatRoom || result.isPolicyExpenseChat;
subtitle = ReportUtils.getChatRoomSubtitle(report);
@@ -1368,6 +1371,7 @@ function getOptions(
transactionViolations = {},
includeTaxRates,
taxRates,
+ includeSelfDM = false,
}: GetOptionsConfig,
): GetOptions {
if (includeCategories) {
@@ -1472,7 +1476,9 @@ function getOptions(
const isTaskReport = ReportUtils.isTaskReport(report);
const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(report);
const isMoneyRequestReport = ReportUtils.isMoneyRequestReport(report);
- const accountIDs = report.visibleChatMemberAccountIDs ?? [];
+ const isSelfDM = ReportUtils.isSelfDM(report);
+ // Currently, currentUser is not included in visibleChatMemberAccountIDs, so for selfDM we need to add the currentUser as participants.
+ const accountIDs = isSelfDM ? [currentUserAccountID ?? 0] : report.visibleChatMemberAccountIDs ?? [];
if (isPolicyExpenseChat && report.isOwnPolicyExpenseChat && !includeOwnedWorkspaceChats) {
return;
@@ -1483,6 +1489,10 @@ function getOptions(
return;
}
+ if (isSelfDM && !includeSelfDM) {
+ return;
+ }
+
if (isThread && !includeThreads) {
return;
}
@@ -1733,6 +1743,7 @@ function getSearchOptions(reports: Record, personalDetails: Onyx
includeThreads: true,
includeMoneyRequests: true,
includeTasks: true,
+ includeSelfDM: true,
});
Timing.end(CONST.TIMING.LOAD_SEARCH_OPTIONS);
Performance.markEnd(CONST.TIMING.LOAD_SEARCH_OPTIONS);
@@ -1808,6 +1819,7 @@ function getFilteredOptions(
includeSelectedOptions = false,
includeTaxRates = false,
taxRates: TaxRatesWithDefault = {} as TaxRatesWithDefault,
+ includeSelfDM = false,
) {
return getOptions(reports, personalDetails, {
betas,
@@ -1829,6 +1841,7 @@ function getFilteredOptions(
includeSelectedOptions,
includeTaxRates,
taxRates,
+ includeSelfDM,
});
}
@@ -1862,6 +1875,7 @@ function getShareDestinationOptions(
excludeLogins,
includeOwnedWorkspaceChats,
excludeUnknownUsers,
+ includeSelfDM: true,
});
}
diff --git a/src/libs/PersonalDetailsUtils.ts b/src/libs/PersonalDetailsUtils.ts
index 4be9ad81184b..9dd60eeebcef 100644
--- a/src/libs/PersonalDetailsUtils.ts
+++ b/src/libs/PersonalDetailsUtils.ts
@@ -24,9 +24,14 @@ Onyx.connect({
},
});
-function getDisplayNameOrDefault(passedPersonalDetails?: Partial | null, defaultValue = '', shouldFallbackToHidden = true): string {
- const displayName = passedPersonalDetails?.displayName ? passedPersonalDetails.displayName.replace(CONST.REGEX.MERGED_ACCOUNT_PREFIX, '') : '';
+function getDisplayNameOrDefault(passedPersonalDetails?: Partial | null, defaultValue = '', shouldFallbackToHidden = true, shouldAddCurrentUserPostfix = false): string {
+ let displayName = passedPersonalDetails?.displayName ? passedPersonalDetails.displayName.replace(CONST.REGEX.MERGED_ACCOUNT_PREFIX, '') : '';
+ if (shouldAddCurrentUserPostfix && !!displayName) {
+ displayName = `${displayName} (${Localize.translateLocal('common.you').toLowerCase()})`;
+ }
+
const fallbackValue = shouldFallbackToHidden ? Localize.translateLocal('common.hidden') : '';
+
return displayName || defaultValue || fallbackValue;
}
diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts
index f64123aceaf8..b2fb456681cf 100644
--- a/src/libs/ReportUtils.ts
+++ b/src/libs/ReportUtils.ts
@@ -399,6 +399,7 @@ type OptionData = {
notificationPreference?: NotificationPreference | null;
isDisabled?: boolean | null;
name?: string | null;
+ isSelfDM?: boolean | null;
} & Report;
type OnyxDataTaskAssigneeChat = {
@@ -909,6 +910,10 @@ function isDM(report: OnyxEntry): boolean {
return isChatReport(report) && !getChatType(report);
}
+function isSelfDM(report: OnyxEntry): boolean {
+ return getChatType(report) === CONST.REPORT.CHAT_TYPE.SELF_DM;
+}
+
/**
* Only returns true if this is our main 1:1 DM report with Concierge
*/
@@ -1611,6 +1616,10 @@ function getIcons(
return isPayer ? [managerIcon, ownerIcon] : [ownerIcon, managerIcon];
}
+ if (isSelfDM(report)) {
+ return getIconsForParticipants([currentUserAccountID ?? 0], personalDetails);
+ }
+
return getIconsForParticipants(report?.participantAccountIDs ?? [], personalDetails);
}
@@ -1633,7 +1642,7 @@ function getPersonalDetailsForAccountID(accountID: number): Partial {
const accountID = Number(user?.accountID);
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
- const displayName = getDisplayNameForParticipant(accountID, isMultipleParticipantReport, shouldFallbackToHidden) || user?.login || '';
+ const displayName = getDisplayNameForParticipant(accountID, isMultipleParticipantReport, shouldFallbackToHidden, shouldAddCurrentUserPostfix) || user?.login || '';
const avatar = UserUtils.getDefaultAvatar(accountID);
let pronouns = user?.pronouns ?? undefined;
@@ -2563,6 +2576,10 @@ function getReportName(report: OnyxEntry, policy: OnyxEntry = nu
formattedName += ` (${Localize.translateLocal('common.archived')})`;
}
+ if (isSelfDM(report)) {
+ formattedName = getDisplayNameForParticipant(currentUserAccountID, undefined, undefined, true);
+ }
+
if (formattedName) {
return formattedName;
}
@@ -2619,6 +2636,11 @@ function getParentNavigationSubtitle(report: OnyxEntry): ParentNavigatio
function navigateToDetailsPage(report: OnyxEntry) {
const participantAccountIDs = report?.participantAccountIDs ?? [];
+ if (isSelfDM(report)) {
+ Navigation.navigate(ROUTES.PROFILE.getRoute(currentUserAccountID ?? 0));
+ return;
+ }
+
if (isOneOnOneChat(report)) {
Navigation.navigate(ROUTES.PROFILE.getRoute(participantAccountIDs[0]));
return;
@@ -3926,6 +3948,7 @@ function shouldReportBeInOptionList({
policies,
excludeEmptyChats,
doesReportHaveViolations,
+ includeSelfDM = false,
}: {
report: OnyxEntry;
currentReportId: string;
@@ -3934,6 +3957,7 @@ function shouldReportBeInOptionList({
policies: OnyxCollection;
excludeEmptyChats: boolean;
doesReportHaveViolations: boolean;
+ includeSelfDM?: boolean;
}) {
const isInDefaultMode = !isInGSDMode;
// Exclude reports that have no data because there wouldn't be anything to show in the option item.
@@ -3955,7 +3979,8 @@ function shouldReportBeInOptionList({
!isUserCreatedPolicyRoom(report) &&
!isArchivedRoom(report) &&
!isMoneyRequestReport(report) &&
- !isTaskReport(report))
+ !isTaskReport(report) &&
+ !isSelfDM(report))
) {
return false;
}
@@ -4017,6 +4042,10 @@ function shouldReportBeInOptionList({
return false;
}
+ if (isSelfDM(report)) {
+ return includeSelfDM;
+ }
+
return true;
}
@@ -4244,7 +4273,7 @@ function hasIOUWaitingOnCurrentUserBankAccount(chatReport: OnyxEntry): b
*/
function canRequestMoney(report: OnyxEntry, policy: OnyxEntry, otherParticipants: number[]): boolean {
// User cannot request money in chat thread or in task report or in chat room
- if (isChatThread(report) || isTaskReport(report) || isChatRoom(report)) {
+ if (isChatThread(report) || isTaskReport(report) || isChatRoom(report) || isSelfDM(report)) {
return false;
}
@@ -4304,7 +4333,7 @@ function canRequestMoney(report: OnyxEntry, policy: OnyxEntry, o
*/
function getMoneyRequestOptions(report: OnyxEntry, policy: OnyxEntry, reportParticipants: number[]): Array> {
// In any thread or task report, we do not allow any new money requests yet
- if (isChatThread(report) || isTaskReport(report)) {
+ if (isChatThread(report) || isTaskReport(report) || isSelfDM(report)) {
return [];
}
@@ -4359,6 +4388,7 @@ function canLeaveRoom(report: OnyxEntry, isPolicyMember: boolean): boole
report?.chatType === CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE ||
report?.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT ||
report?.chatType === CONST.REPORT.CHAT_TYPE.DOMAIN_ALL ||
+ report?.chatType === CONST.REPORT.CHAT_TYPE.SELF_DM ||
!report?.chatType
) {
// DM chats don't have a chatType
@@ -5187,6 +5217,7 @@ export {
getAddWorkspaceRoomOrChatReportErrors,
getReportOfflinePendingActionAndErrors,
isDM,
+ isSelfDM,
getPolicy,
getPolicyExpenseChatReportIDByOwner,
getWorkspaceChats,
diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts
index 35cf52a5ff99..a9cbefddec94 100644
--- a/src/libs/SidebarUtils.ts
+++ b/src/libs/SidebarUtils.ts
@@ -92,6 +92,7 @@ function getOrderedReportIDs(
policies,
excludeEmptyChats: true,
doesReportHaveViolations,
+ includeSelfDM: true,
});
});
@@ -221,7 +222,14 @@ function getOptionData({
isDeletedParentAction: false,
};
- const participantPersonalDetailList = Object.values(OptionsListUtils.getPersonalDetailsForAccountIDs(report.participantAccountIDs ?? [], personalDetails)) as PersonalDetails[];
+ let participantAccountIDs = report.participantAccountIDs ?? [];
+
+ // Currently, currentUser is not included in participantAccountIDs, so for selfDM we need to add the currentUser(report owner) as participants.
+ if (ReportUtils.isSelfDM(report)) {
+ participantAccountIDs = [report.ownerAccountID ?? 0];
+ }
+
+ const participantPersonalDetailList = Object.values(OptionsListUtils.getPersonalDetailsForAccountIDs(participantAccountIDs, personalDetails)) as PersonalDetails[];
const personalDetail = participantPersonalDetailList[0] ?? {};
const hasErrors = Object.keys(result.allReportErrors ?? {}).length !== 0;
@@ -258,6 +266,7 @@ function getOptionData({
result.isAllowedToComment = ReportUtils.canUserPerformWriteAction(report);
result.chatType = report.chatType;
result.isDeletedParentAction = report.isDeletedParentAction;
+ result.isSelfDM = ReportUtils.isSelfDM(report);
const hasMultipleParticipants = participantPersonalDetailList.length > 1 || result.isChatRoom || result.isPolicyExpenseChat || ReportUtils.isExpenseReport(report);
const subtitle = ReportUtils.getChatRoomSubtitle(report);
@@ -267,7 +276,12 @@ function getOptionData({
const formattedLogin = Str.isSMSLogin(login) ? LocalePhoneNumber.formatPhoneNumber(login) : login;
// We only create tooltips for the first 10 users or so since some reports have hundreds of users, causing performance to degrade.
- const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips((participantPersonalDetailList || []).slice(0, 10), hasMultipleParticipants);
+ const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips(
+ (participantPersonalDetailList || []).slice(0, 10),
+ hasMultipleParticipants,
+ undefined,
+ ReportUtils.isSelfDM(report),
+ );
// If the last actor's details are not currently saved in Onyx Collection,
// then try to get that from the last report action if that action is valid
diff --git a/src/pages/ProfilePage.js b/src/pages/ProfilePage.js
index 0b986adf1c6f..cf05b8e4ab28 100755
--- a/src/pages/ProfilePage.js
+++ b/src/pages/ProfilePage.js
@@ -95,9 +95,10 @@ const getPhoneNumber = (details) => {
function ProfilePage(props) {
const styles = useThemeStyles();
const accountID = Number(lodashGet(props.route.params, 'accountID', 0));
- const details = lodashGet(props.personalDetails, accountID, ValidationUtils.isValidAccountRoute(accountID) ? {} : {isloading: false});
+ const isCurrentUser = props.session.accountID === accountID;
- const displayName = PersonalDetailsUtils.getDisplayNameOrDefault(details);
+ const details = lodashGet(props.personalDetails, accountID, ValidationUtils.isValidAccountRoute(accountID) ? {} : {isloading: false});
+ const displayName = PersonalDetailsUtils.getDisplayNameOrDefault(details, undefined, undefined, isCurrentUser);
const avatar = lodashGet(details, 'avatar', UserUtils.getDefaultAvatar());
const fallbackIcon = lodashGet(details, 'fallbackIcon', '');
const login = lodashGet(details, 'login', '');
@@ -116,7 +117,6 @@ function ProfilePage(props) {
const phoneNumber = getPhoneNumber(details);
const phoneOrEmail = isSMSLogin ? getPhoneNumber(details) : login;
- const isCurrentUser = props.session.accountID === accountID;
const hasMinimumDetails = !_.isEmpty(details.avatar);
const isLoading = lodashGet(details, 'isLoading', false) || _.isEmpty(details);
@@ -130,7 +130,7 @@ function ProfilePage(props) {
const navigateBackTo = lodashGet(props.route, 'params.backTo');
- const shouldShowNotificationPreference = !_.isEmpty(props.report) && props.report.notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN;
+ const shouldShowNotificationPreference = !_.isEmpty(props.report) && !isCurrentUser && props.report.notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN;
const notificationPreference = shouldShowNotificationPreference ? props.translate(`notificationPreferencesPage.notificationPreferences.${props.report.notificationPreference}`) : '';
// eslint-disable-next-line rulesdir/prefer-early-return
@@ -234,7 +234,7 @@ function ProfilePage(props) {
shouldShowRightIcon
/>
)}
- {!_.isEmpty(props.report) && (
+ {!_.isEmpty(props.report) && !isCurrentUser && (