@@ -70,30 +70,42 @@ class Hm_MessagesStore {
7070 const sourcesToRemove = Object . keys ( this . sources ) . filter ( key => ! this . currentlyAvailableSources ( ) . includes ( key ) ) ;
7171 sourcesToRemove . forEach ( key => delete this . sources [ key ] ) ;
7272
73- this . fetch ( hideLoadingState ) . forEach ( async ( req ) => {
74- const { formatted_message_list : updatedMessages , pages, folder_status, do_not_flag_as_read_on_open, sourceId } = await req ;
75- // count and pages only available in non-combined pages where there is only one ajax call, so it is safe to overwrite
76- this . count = folder_status && Object . values ( folder_status ) [ 0 ] ?. messages ;
77- this . pages = parseInt ( pages ) ;
78- this . newMessages = this . getNewMessages ( updatedMessages ) ;
79-
80- if ( typeof do_not_flag_as_read_on_open == 'booelan' ) {
81- this . flagAsReadOnOpen = ! do_not_flag_as_read_on_open ;
82- }
73+ // Batch processing for multiple requests
74+ const pendingResponses = new Map ( ) ;
75+ let processingTimeout = null ;
8376
84- if ( this . sources [ sourceId ] ) {
85- this . rows = this . rows . filter ( row => ! this . sources [ sourceId ] . includes ( row [ '1' ] ) ) ;
86- }
87- this . sources [ sourceId ] = Object . keys ( updatedMessages ) ;
88- for ( const id in updatedMessages ) {
89- if ( this . rows . map ( row => row [ '1' ] ) . indexOf ( id ) === - 1 ) {
90- this . rows . push ( updatedMessages [ id ] ) ;
91- } else {
92- const index = this . rows . map ( row => row [ '1' ] ) . indexOf ( id ) ;
93- this . rows [ index ] = updatedMessages [ id ] ;
77+ const processPendingResponses = ( ) => {
78+ if ( pendingResponses . size === 0 ) return ;
79+
80+ // Process all pending responses at once
81+ const responses = Array . from ( pendingResponses . values ( ) ) ;
82+ pendingResponses . clear ( ) ;
83+
84+ responses . forEach ( ( { formatted_message_list : updatedMessages , pages, folder_status, do_not_flag_as_read_on_open, sourceId } ) => {
85+ // count and pages only available in non-combined pages where there is only one ajax call, so it is safe to overwrite
86+ this . count = folder_status && Object . values ( folder_status ) [ 0 ] ?. messages ;
87+ this . pages = parseInt ( pages ) ;
88+ this . newMessages = this . getNewMessages ( updatedMessages ) ;
89+
90+ if ( typeof do_not_flag_as_read_on_open == 'booelan' ) {
91+ this . flagAsReadOnOpen = ! do_not_flag_as_read_on_open ;
9492 }
95- }
9693
94+ if ( this . sources [ sourceId ] ) {
95+ this . rows = this . rows . filter ( row => ! this . sources [ sourceId ] . includes ( row [ '1' ] ) ) ;
96+ }
97+ this . sources [ sourceId ] = Object . keys ( updatedMessages ) ;
98+ for ( const id in updatedMessages ) {
99+ if ( this . rows . map ( row => row [ '1' ] ) . indexOf ( id ) === - 1 ) {
100+ this . rows . push ( updatedMessages [ id ] ) ;
101+ } else {
102+ const index = this . rows . map ( row => row [ '1' ] ) . indexOf ( id ) ;
103+ this . rows [ index ] = updatedMessages [ id ] ;
104+ }
105+ }
106+ } ) ;
107+
108+ // Do expensive operations only once for all responses
97109 if ( this . path == 'unread' ) {
98110 $ ( '.total_unread_count' ) . html ( ' ' + this . rows . length + ' ' ) ;
99111 }
@@ -104,6 +116,21 @@ class Hm_MessagesStore {
104116 if ( messagesReadyCB ) {
105117 messagesReadyCB ( this ) ;
106118 }
119+ } ;
120+
121+ this . fetch ( hideLoadingState ) . forEach ( ( req ) => {
122+ req . then ( ( response ) => {
123+ pendingResponses . set ( response . sourceId , response ) ;
124+
125+ if ( processingTimeout ) {
126+ clearTimeout ( processingTimeout ) ;
127+ }
128+
129+ // Process after a short delay to allow batching
130+ processingTimeout = setTimeout ( processPendingResponses , 10 ) ;
131+ } ) . catch ( ( error ) => {
132+ console . error ( 'Error loading messages from source:' , error ) ;
133+ } ) ;
107134 } ) ;
108135
109136 return this ;
0 commit comments