Skip to content

Commit c372808

Browse files
committed
feat: proper sorting in reducer
1 parent 53a2d6c commit c372808

2 files changed

Lines changed: 33 additions & 8 deletions

File tree

packages/api/src/providers/GroupActivities/private/createDefaultGroupActivitiesMiddleware.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* eslint-disable no-magic-numbers */
21
import { getOrgSchemaMessage, type GlobalScopePonyfill, type WebChatActivity } from 'botframework-webchat-core';
32

43
import type GroupActivitiesMiddleware from '../../../types/GroupActivitiesMiddleware';
@@ -102,9 +101,8 @@ export default function createDefaultGroupActivitiesMiddleware({
102101
([last], [current]) =>
103102
typeof last?.isPartOf?.['@id'] === 'string' && last.isPartOf['@id'] === current?.isPartOf?.['@id']
104103
).map(bin =>
105-
bin
106-
.toSorted(([m1], [m2]) => (m1.position < m2.position ? -1 : m1.position > m2.position ? 1 : 0))
107-
.map(([, activity]) => activity)
104+
// Position-based sorting is now handled at the reducer level
105+
bin.map(([, activity]) => activity)
108106
)
109107
};
110108
}

packages/core/src/reducers/createActivitiesReducer.ts

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
} from '../actions/postActivity';
1414
import { SENDING, SEND_FAILED, SENT } from '../types/internal/SendStatus';
1515
import getActivityLivestreamingMetadata from '../utils/getActivityLivestreamingMetadata';
16+
import getOrgSchemaMessage from '../utils/getOrgSchemaMessage';
1617
import findBeforeAfter from './private/findBeforeAfter';
1718

1819
import type { Reducer } from 'redux';
@@ -74,6 +75,10 @@ function patchActivity(
7475
activity = updateIn(activity, ['channelData'], channelData => ({ ...channelData }));
7576
activity = updateIn(activity, ['channelData', 'webChat', 'receivedAt'], () => Date.now());
7677

78+
const messageEntity = getOrgSchemaMessage(activity.entities);
79+
const entityPosition = messageEntity?.position;
80+
const entityPartOf = messageEntity?.isPartOf?.['@id'];
81+
7782
const {
7883
channelData: { 'webchat:sequence-id': sequenceId }
7984
} = activity;
@@ -128,6 +133,13 @@ function patchActivity(
128133
activity = updateIn(activity, ['channelData', 'webchat:sequence-id'], () => sequenceId);
129134
}
130135

136+
if (typeof entityPosition === 'number') {
137+
activity = updateIn(activity, ['channelData', 'webchat:entity-position'], () => entityPosition);
138+
}
139+
if (typeof entityPartOf === 'string') {
140+
activity = updateIn(activity, ['channelData', 'webchat:entity-part-of'], () => entityPartOf);
141+
}
142+
131143
return activity;
132144
}
133145

@@ -165,10 +177,25 @@ function upsertActivityWithSort(
165177
!(nextClientActivityID && clientActivityID === nextClientActivityID) && !(id && id === nextActivity.id)
166178
);
167179

168-
// Then, find the right (sorted) place to insert the new activity at, based on sequence ID.
169-
const indexToInsert = nextActivities.findIndex(
170-
({ channelData: { 'webchat:sequence-id': sequenceId } = {} }) => (sequenceId || 0) > (nextSequenceId || 0)
171-
);
180+
const nextEntityPosition = nextActivity.channelData?.['webchat:entity-position'];
181+
const nextPartOf = nextActivity.channelData?.['webchat:entity-part-of'];
182+
183+
const indexToInsert = nextActivities.findIndex(({ channelData = {} }) => {
184+
const currentSequenceId = channelData['webchat:sequence-id'] || 0;
185+
const currentPosition = channelData['webchat:entity-position'];
186+
const currentPartOf = channelData['webchat:entity-part-of'];
187+
188+
const bothHavePosition = typeof currentPosition === 'number' && typeof nextEntityPosition === 'number';
189+
const bothArePartOf = typeof currentPartOf === 'string' && currentPartOf === nextPartOf;
190+
191+
// For activities in the same creative work part, position is primary sort key
192+
if (bothHavePosition && bothArePartOf) {
193+
return currentPosition > nextEntityPosition;
194+
}
195+
196+
// For activities not in the same part or without positions follow sequence ID order
197+
return (currentSequenceId || 0) > (nextSequenceId || 0);
198+
});
172199

173200
// If no right place are found, append it
174201
nextActivities.splice(~indexToInsert ? indexToInsert : nextActivities.length, 0, nextActivity);

0 commit comments

Comments
 (0)