@@ -160,6 +160,7 @@ import {
160160 isIOUReportUsingReport ,
161161 isMoneyRequestReport ,
162162 isOpenExpenseReport ,
163+ isOptimisticPersonalDetail ,
163164 isProcessingReport ,
164165 isReportManuallyReimbursed ,
165166 isReportNotFound ,
@@ -1879,22 +1880,26 @@ function pruneReportActionPagesToNewestWindow(reportID: string | undefined, sort
18791880 * Create a group chat report. Simplified version specifically for group chats without unnecessary logic.
18801881 *
18811882 * @param reportID The ID of the group chat report to open
1882- * @param participantLoginList The list of user logins included in the group chat
1883+ * @param participantsPersonalDetails The personal details of the participants included in the group chat. Logins and accountIDs are derived from this, and entries flagged with `isOptimisticPersonalDetail` are the new participants we still need to create optimistic personal details for.
18831884 * @param newReportObject The optimistic report object for the new group chat
18841885 * @param currentUserLogin The login of the current user
18851886 * @param introSelected The intro selected data for guided setup
18861887 * @param avatar The avatar file to upload for the group chat (optional)
18871888 */
18881889function createGroupChat (
18891890 reportID : string ,
1890- participantLoginList : string [ ] ,
1891+ participantsPersonalDetails : OnyxEntry < PersonalDetailsList > ,
18911892 newReportObject : OptimisticChatReport ,
18921893 currentUserLogin : string ,
18931894 introSelected : OnyxEntry < IntroSelected > ,
18941895 isSelfTourViewed : boolean | undefined ,
18951896 betas : OnyxEntry < Beta [ ] > ,
18961897 avatar ?: File | CustomRNImageManipulatorResult ,
18971898) {
1899+ const participantLoginList = Object . values ( participantsPersonalDetails ?? { } )
1900+ . map ( ( participant ) => participant ?. login )
1901+ . filter ( ( login ) : login is string => ! ! login ) ;
1902+
18981903 const optimisticReport = {
18991904 reportName : CONST . REPORT . DEFAULT_REPORT_NAME ,
19001905 } ;
@@ -2015,7 +2020,7 @@ function createGroupChat(
20152020
20162021 for ( const [ index , login ] of participantLoginList . entries ( ) ) {
20172022 const accountID = participantAccountIDs . at ( index ) ?? - 1 ;
2018- const isOptimisticAccount = ! allPersonalDetails ?. [ accountID ] ;
2023+ const isOptimisticAccount = isOptimisticPersonalDetail ( accountID ) ;
20192024
20202025 if ( ! isOptimisticAccount ) {
20212026 continue ;
@@ -2338,8 +2343,9 @@ function navigateToAndOpenReport(
23382343 navigateToReport ( chat . reportID , { shouldDismissModal, ...linkToOptions } ) ;
23392344}
23402345
2346+ // TODO: update to object structure https://github.com/Expensify/App/issues/73656
23412347function navigateToAndCreateGroupChat (
2342- userLogins : string [ ] ,
2348+ participantsPersonalDetails : OnyxEntry < PersonalDetailsList > ,
23432349 reportName : string ,
23442350 currentUserLogin : string ,
23452351 optimisticReportID : string ,
@@ -2350,11 +2356,14 @@ function navigateToAndCreateGroupChat(
23502356 avatarUri ?: string ,
23512357 avatarFile ?: File | CustomRNImageManipulatorResult | undefined ,
23522358) {
2359+ const userLogins = Object . values ( participantsPersonalDetails ?? { } )
2360+ . map ( ( participant ) => participant ?. login )
2361+ . filter ( ( login ) : login is string => ! ! login ) ;
23532362 const participantAccountIDs = PersonalDetailsUtils . getAccountIDsByLogins ( userLogins ) ;
23542363
23552364 // If we are creating a group chat then participantAccountIDs is expected to contain currentUserAccountID
23562365 const newChat = buildOptimisticGroupChatReport ( participantAccountIDs , reportName , avatarUri ?? '' , currentUserAccountID , optimisticReportID , CONST . REPORT . NOTIFICATION_PREFERENCE . HIDDEN ) ;
2357- createGroupChat ( newChat . reportID , userLogins , newChat , currentUserLogin , introSelected , isSelfTourViewed , betas , avatarFile ) ;
2366+ createGroupChat ( newChat . reportID , participantsPersonalDetails , newChat , currentUserLogin , introSelected , isSelfTourViewed , betas , avatarFile ) ;
23582367
23592368 navigateToReport ( newChat . reportID , { afterTransition : clearGroupChat } ) ;
23602369}
@@ -2455,10 +2464,11 @@ function navigateToAndOpenChildReport(
24552464 currentUserAccountID : number ,
24562465 introSelected : OnyxEntry < IntroSelected > ,
24572466 betas : OnyxEntry < Beta [ ] > ,
2458- personalDetails : OnyxEntry < PersonalDetailsList > ,
2467+ // The personal details of the child report participants (the current user and the parent action's actor).
2468+ participantsPersonalDetails : OnyxEntry < PersonalDetailsList > ,
24592469 isSelfTourViewed : boolean | undefined ,
24602470) {
2461- const report = childReport ?? createChildReport ( childReport , parentReportAction , parentReport , currentUserAccountID , introSelected , betas , isSelfTourViewed , personalDetails ) ;
2471+ const report = childReport ?? createChildReport ( childReport , parentReportAction , parentReport , currentUserAccountID , introSelected , betas , isSelfTourViewed , participantsPersonalDetails ) ;
24622472
24632473 if ( isSearchTopmostFullScreenRoute ( ) ) {
24642474 Navigation . navigate ( ROUTES . SEARCH_REPORT . getRoute ( { reportID : report . reportID , backTo : Navigation . getActiveRoute ( ) } ) ) ;
@@ -2480,8 +2490,8 @@ function createChildReport(
24802490 introSelected : OnyxEntry < IntroSelected > ,
24812491 betas : OnyxEntry < Beta [ ] > ,
24822492 isSelfTourViewed : boolean | undefined ,
2483- // TODO: personalDetails should be a required field in follow-up PRs https://github.com/Expensify/App/issues/73656
2484- personalDetails ? : OnyxEntry < PersonalDetailsList > ,
2493+ // The personal details of the child report participants (the current user and the parent action's actor).
2494+ participantsPersonalDetails : OnyxEntry < PersonalDetailsList > ,
24852495) : Report {
24862496 const participantAccountIDs = [ ...new Set ( [ currentUserAccountID , Number ( parentReportAction . actorAccountID ) ] ) ] ;
24872497 // Threads from DMs and selfDMs don't have a chatType. All other threads inherit the chatType from their parent
@@ -2519,8 +2529,7 @@ function createChildReport(
25192529 reportID : newChat . reportID ,
25202530 introSelected,
25212531 participants,
2522- // TODO: allPersonalDetails fallback should be removed in follow-up PRs https://github.com/Expensify/App/issues/73656
2523- personalDetails : personalDetails ?? allPersonalDetails ,
2532+ personalDetails : participantsPersonalDetails ,
25242533 newReportObject : newChat ,
25252534 parentReportActionID : parentReportAction . reportActionID ,
25262535 isNewThread : true ,
@@ -2538,6 +2547,8 @@ function createChildReport(
25382547 * Creates an explanation thread for a report action with reasoning
25392548 * Adds a "Please explain this to me." comment from the user
25402549 */
2550+ // TODO: update to object structure https://github.com/Expensify/App/issues/73656
2551+ // eslint-disable-next-line @typescript-eslint/max-params
25412552function explain (
25422553 childReport : OnyxEntry < Report > ,
25432554 originalReport : OnyxEntry < Report > ,
@@ -2548,14 +2559,16 @@ function explain(
25482559 betas : OnyxEntry < Beta [ ] > ,
25492560 isSelfTourViewed : boolean | undefined ,
25502561 delegateAccountID : number | undefined ,
2562+ // The personal details of the explanation thread participants (the current user and the report action's actor).
2563+ participantsPersonalDetails : OnyxEntry < PersonalDetailsList > ,
25512564 timezone : Timezone = CONST . DEFAULT_TIME_ZONE ,
25522565) {
25532566 if ( ! originalReport ?. reportID || ! reportAction ) {
25542567 return ;
25552568 }
25562569
25572570 // Check if explanation thread report already exists
2558- const report = childReport ?? createChildReport ( childReport , reportAction , originalReport , currentUserAccountID , introSelected , betas , isSelfTourViewed ) ;
2571+ const report = childReport ?? createChildReport ( childReport , reportAction , originalReport , currentUserAccountID , introSelected , betas , isSelfTourViewed , participantsPersonalDetails ) ;
25592572
25602573 if ( isSearchTopmostFullScreenRoute ( ) ) {
25612574 Navigation . navigate ( ROUTES . SEARCH_REPORT . getRoute ( { reportID : report . reportID , backTo : Navigation . getActiveRoute ( ) } ) ) ;
0 commit comments