stream-chat-react 12.8.1 → 12.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2531,9 +2531,9 @@ var require_unified = __commonJS({
2531
2531
  return typeof value === "function" && value.prototype && // A function with keys in its prototype is probably a constructor.
2532
2532
  // Classes’ prototype methods are not enumerable, so we check if some value
2533
2533
  // exists in the prototype.
2534
- (keys2(value.prototype) || name in value.prototype);
2534
+ (keys3(value.prototype) || name in value.prototype);
2535
2535
  }
2536
- function keys2(value) {
2536
+ function keys3(value) {
2537
2537
  var key;
2538
2538
  for (key in value) {
2539
2539
  return true;
@@ -18902,14 +18902,14 @@ var require_mml_react_cjs_development = __commonJS({
18902
18902
  this.reset(true);
18903
18903
  }
18904
18904
  exports3.keys = function(object) {
18905
- var keys2 = [];
18905
+ var keys3 = [];
18906
18906
  for (var key in object) {
18907
- keys2.push(key);
18907
+ keys3.push(key);
18908
18908
  }
18909
- keys2.reverse();
18909
+ keys3.reverse();
18910
18910
  return function next() {
18911
- while (keys2.length) {
18912
- var key2 = keys2.pop();
18911
+ while (keys3.length) {
18912
+ var key2 = keys3.pop();
18913
18913
  if (key2 in object) {
18914
18914
  next.value = key2;
18915
18915
  next.done = false;
@@ -20319,6 +20319,7 @@ __export(src_exports, {
20319
20319
  enTranslations: () => en_default,
20320
20320
  esTranslations: () => es_default,
20321
20321
  escapeRegExp: () => escapeRegExp,
20322
+ extractSortValue: () => extractSortValue,
20322
20323
  findLastPinnedChannelIndex: () => findLastPinnedChannelIndex,
20323
20324
  frTranslations: () => fr_default,
20324
20325
  getChannel: () => getChannel,
@@ -20327,6 +20328,7 @@ __export(src_exports, {
20327
20328
  getGroupChannelDisplayInfo: () => getGroupChannelDisplayInfo,
20328
20329
  getGroupStyles: () => getGroupStyles,
20329
20330
  getImages: () => getImages,
20331
+ getIsFirstUnreadMessage: () => getIsFirstUnreadMessage,
20330
20332
  getLastReceived: () => getLastReceived,
20331
20333
  getLatestMessagePreview: () => getLatestMessagePreview,
20332
20334
  getMessageActions: () => getMessageActions,
@@ -20781,16 +20783,16 @@ var import_react7 = require("react");
20781
20783
 
20782
20784
  // src/store/hooks/useStateStore.ts
20783
20785
  var import_react6 = require("react");
20784
- function useStateStore(store, selector6) {
20786
+ function useStateStore(store, selector7) {
20785
20787
  const [state, setState] = (0, import_react6.useState)(() => {
20786
20788
  if (!store) return void 0;
20787
- return selector6(store.getLatestValue());
20789
+ return selector7(store.getLatestValue());
20788
20790
  });
20789
20791
  (0, import_react6.useEffect)(() => {
20790
20792
  if (!store) return;
20791
- const unsubscribe = store.subscribeWithSelector(selector6, setState);
20793
+ const unsubscribe = store.subscribeWithSelector(selector7, setState);
20792
20794
  return unsubscribe;
20793
- }, [store, selector6]);
20795
+ }, [store, selector7]);
20794
20796
  return state;
20795
20797
  }
20796
20798
 
@@ -44527,7 +44529,10 @@ var moveChannelUpwards = ({
44527
44529
  const targetChannelExistsWithinList = targetChannelIndex >= 0;
44528
44530
  const targetChannelAlreadyAtTheTop = targetChannelIndex === 0;
44529
44531
  const considerPinnedChannels = shouldConsiderPinnedChannels(sort);
44530
- if (targetChannelAlreadyAtTheTop) return channels;
44532
+ const isTargetChannelPinned = isChannelPinned(channelToMove);
44533
+ if (targetChannelAlreadyAtTheTop || considerPinnedChannels && isTargetChannelPinned) {
44534
+ return channels;
44535
+ }
44531
44536
  const newChannels = [...channels];
44532
44537
  if (targetChannelExistsWithinList) {
44533
44538
  newChannels.splice(targetChannelIndex, 1);
@@ -44544,25 +44549,48 @@ var moveChannelUpwards = ({
44544
44549
  return newChannels;
44545
44550
  };
44546
44551
  var shouldConsiderPinnedChannels = (sort) => {
44547
- if (!sort) return false;
44548
- if (!Array.isArray(sort)) return false;
44549
- const [option] = sort;
44550
- if (!option?.pinned_at) return false;
44551
- return Math.abs(option.pinned_at) === 1;
44552
+ const value = extractSortValue({ atIndex: 0, sort, targetKey: "pinned_at" });
44553
+ if (typeof value !== "number") return false;
44554
+ return Math.abs(value) === 1;
44555
+ };
44556
+ var extractSortValue = ({
44557
+ atIndex,
44558
+ sort,
44559
+ targetKey
44560
+ }) => {
44561
+ if (!sort) return null;
44562
+ let option = null;
44563
+ if (Array.isArray(sort)) {
44564
+ option = sort[atIndex] ?? null;
44565
+ } else {
44566
+ let index3 = 0;
44567
+ for (const key in sort) {
44568
+ if (index3 !== atIndex) {
44569
+ index3++;
44570
+ continue;
44571
+ }
44572
+ if (key !== targetKey) {
44573
+ return null;
44574
+ }
44575
+ option = sort;
44576
+ break;
44577
+ }
44578
+ }
44579
+ return option?.[targetKey] ?? null;
44552
44580
  };
44553
44581
  var shouldConsiderArchivedChannels = (filters) => {
44554
44582
  if (!filters) return false;
44555
- return !filters.archived;
44583
+ return typeof filters.archived === "boolean";
44556
44584
  };
44557
44585
  var isChannelPinned = (channel) => {
44558
44586
  if (!channel) return false;
44559
- const member = channel.state.membership;
44560
- return !!member?.pinned_at;
44587
+ const membership = channel.state.membership;
44588
+ return typeof membership.pinned_at === "string";
44561
44589
  };
44562
44590
  var isChannelArchived = (channel) => {
44563
44591
  if (!channel) return false;
44564
- const member = channel.state.membership;
44565
- return !!member?.archived_at;
44592
+ const membership = channel.state.membership;
44593
+ return typeof membership.archived_at === "string";
44566
44594
  };
44567
44595
 
44568
44596
  // src/components/ChannelList/hooks/usePaginatedChannels.ts
@@ -45425,33 +45453,33 @@ var useChannelListShapeDefaults = () => {
45425
45453
  if (typeof customHandler === "function") {
45426
45454
  return customHandler(setChannels, event);
45427
45455
  }
45428
- setChannels((channels) => {
45429
- const targetChannelIndex = channels.findIndex((channel) => channel.cid === event.cid);
45456
+ const channelType = event.channel_type;
45457
+ const channelId = event.channel_id;
45458
+ if (!channelType || !channelId) return;
45459
+ setChannels((currentChannels) => {
45460
+ const targetChannel = client.channel(channelType, channelId);
45461
+ const targetChannelIndex = currentChannels.indexOf(targetChannel);
45430
45462
  const targetChannelExistsWithinList = targetChannelIndex >= 0;
45431
- const targetChannel = channels[targetChannelIndex];
45432
45463
  const isTargetChannelPinned = isChannelPinned(targetChannel);
45433
45464
  const isTargetChannelArchived = isChannelArchived(targetChannel);
45434
45465
  const considerArchivedChannels = shouldConsiderArchivedChannels(filters);
45435
45466
  const considerPinnedChannels = shouldConsiderPinnedChannels(sort);
45436
45467
  if (
45437
- // target channel is archived
45438
- isTargetChannelArchived && considerArchivedChannels || // target channel is pinned
45439
- isTargetChannelPinned && considerPinnedChannels || // list order is locked
45468
+ // filter is defined, target channel is archived and filter option is set to false
45469
+ considerArchivedChannels && isTargetChannelArchived && !filters.archived || // filter is defined, target channel isn't archived and filter option is set to true
45470
+ considerArchivedChannels && !isTargetChannelArchived && filters.archived || // sort option is defined, target channel is pinned
45471
+ considerPinnedChannels && isTargetChannelPinned || // list order is locked
45440
45472
  lockChannelOrder || // target channel is not within the loaded list and loading from cache is disallowed
45441
45473
  !targetChannelExistsWithinList && !allowNewMessagesFromUnfilteredChannels
45442
45474
  ) {
45443
- return channels;
45444
- }
45445
- const channelToMove = channels[targetChannelIndex] ?? (allowNewMessagesFromUnfilteredChannels && event.channel_type ? client.channel(event.channel_type, event.channel_id) : null);
45446
- if (channelToMove) {
45447
- return moveChannelUpwards({
45448
- channels,
45449
- channelToMove,
45450
- channelToMoveIndexWithinChannels: targetChannelIndex,
45451
- sort
45452
- });
45475
+ return currentChannels;
45453
45476
  }
45454
- return channels;
45477
+ return moveChannelUpwards({
45478
+ channels: currentChannels,
45479
+ channelToMove: targetChannel,
45480
+ channelToMoveIndexWithinChannels: targetChannelIndex,
45481
+ sort
45482
+ });
45455
45483
  });
45456
45484
  },
45457
45485
  [client]
@@ -45477,7 +45505,7 @@ var useChannelListShapeDefaults = () => {
45477
45505
  type: event.channel.type
45478
45506
  });
45479
45507
  const considerArchivedChannels = shouldConsiderArchivedChannels(filters);
45480
- if (isChannelArchived(channel) && considerArchivedChannels) {
45508
+ if (isChannelArchived(channel) && considerArchivedChannels && !filters.archived) {
45481
45509
  return;
45482
45510
  }
45483
45511
  if (!allowNewMessagesFromUnfilteredChannels) {
@@ -45499,26 +45527,33 @@ var useChannelListShapeDefaults = () => {
45499
45527
  allowNewMessagesFromUnfilteredChannels,
45500
45528
  customHandler,
45501
45529
  event,
45502
- setChannels
45530
+ setChannels,
45531
+ sort
45503
45532
  }) => {
45504
45533
  if (typeof customHandler === "function") {
45505
45534
  return customHandler(setChannels, event);
45506
45535
  }
45507
- if (allowNewMessagesFromUnfilteredChannels && event.channel?.type) {
45508
- const channel = await getChannel({
45509
- client,
45510
- id: event.channel.id,
45511
- members: event.channel.members?.reduce((acc, { user, user_id }) => {
45512
- const userId = user_id || user?.id;
45513
- if (userId) {
45514
- acc.push(userId);
45515
- }
45516
- return acc;
45517
- }, []),
45518
- type: event.channel.type
45519
- });
45520
- setChannels((channels) => (0, import_lodash11.default)([channel, ...channels], "cid"));
45536
+ if (!event.channel || !allowNewMessagesFromUnfilteredChannels) {
45537
+ return;
45521
45538
  }
45539
+ const channel = await getChannel({
45540
+ client,
45541
+ id: event.channel.id,
45542
+ members: event.channel.members?.reduce((newMembers, { user, user_id }) => {
45543
+ const userId = user_id || user?.id;
45544
+ if (userId) newMembers.push(userId);
45545
+ return newMembers;
45546
+ }, []),
45547
+ type: event.channel.type
45548
+ });
45549
+ setChannels(
45550
+ (channels) => moveChannelUpwards({
45551
+ channels,
45552
+ channelToMove: channel,
45553
+ channelToMoveIndexWithinChannels: -1,
45554
+ sort
45555
+ })
45556
+ );
45522
45557
  },
45523
45558
  [client]
45524
45559
  );
@@ -45536,29 +45571,37 @@ var useChannelListShapeDefaults = () => {
45536
45571
  []
45537
45572
  );
45538
45573
  const handleMemberUpdated = (0, import_react101.useCallback)(
45539
- ({ event, lockChannelOrder, setChannels, sort }) => {
45574
+ ({
45575
+ event,
45576
+ filters,
45577
+ lockChannelOrder,
45578
+ setChannels,
45579
+ sort
45580
+ }) => {
45540
45581
  if (!event.member?.user || event.member.user.id !== client.userID || !event.channel_type) {
45541
45582
  return;
45542
45583
  }
45543
- const member = event.member;
45544
45584
  const channelType = event.channel_type;
45545
45585
  const channelId = event.channel_id;
45546
45586
  const considerPinnedChannels = shouldConsiderPinnedChannels(sort);
45547
- const pinnedAtSort = Array.isArray(sort) ? sort[0]?.pinned_at ?? null : null;
45587
+ const considerArchivedChannels = shouldConsiderArchivedChannels(filters);
45588
+ const pinnedAtSort = extractSortValue({ atIndex: 0, sort, targetKey: "pinned_at" });
45548
45589
  setChannels((currentChannels) => {
45549
45590
  const targetChannel = client.channel(channelType, channelId);
45550
45591
  const targetChannelIndex = currentChannels.indexOf(targetChannel);
45551
45592
  const targetChannelExistsWithinList = targetChannelIndex >= 0;
45593
+ const isTargetChannelArchived = isChannelArchived(targetChannel);
45594
+ const isTargetChannelPinned = isChannelPinned(targetChannel);
45552
45595
  if (!considerPinnedChannels || lockChannelOrder) return currentChannels;
45553
45596
  const newChannels = [...currentChannels];
45554
45597
  if (targetChannelExistsWithinList) {
45555
45598
  newChannels.splice(targetChannelIndex, 1);
45556
45599
  }
45557
- if (typeof member.archived_at === "string") {
45600
+ if (considerArchivedChannels && isTargetChannelArchived && !filters.archived || considerArchivedChannels && !isTargetChannelArchived && filters.archived) {
45558
45601
  return newChannels;
45559
45602
  }
45560
45603
  let lastPinnedChannelIndex = null;
45561
- if (pinnedAtSort === 1 || pinnedAtSort === -1 && !member.pinned_at) {
45604
+ if (pinnedAtSort === 1 || pinnedAtSort === -1 && !isTargetChannelPinned) {
45562
45605
  lastPinnedChannelIndex = findLastPinnedChannelIndex({ channels: newChannels });
45563
45606
  }
45564
45607
  const newTargetChannelIndex = typeof lastPinnedChannelIndex === "number" ? lastPinnedChannelIndex + 1 : 0;
@@ -45759,6 +45802,7 @@ var usePrepareShapeHandlers = ({
45759
45802
  case "member.updated":
45760
45803
  defaults.handleMemberUpdated({
45761
45804
  event,
45805
+ filters,
45762
45806
  lockChannelOrder,
45763
45807
  setChannels,
45764
45808
  sort
@@ -46242,24 +46286,41 @@ var useUserPresenceChangedListener = (setChannels) => {
46242
46286
  }, [client, setChannels]);
46243
46287
  };
46244
46288
 
46245
- // src/components/ChannelList/hooks/useChannelMembershipState.ts
46289
+ // src/components/ChannelList/hooks/useSelectedChannelState.ts
46246
46290
  var import_react113 = require("react");
46247
- var useChannelMembershipState = (channel) => {
46248
- const [membership, setMembership] = (0, import_react113.useState)(
46249
- channel?.state.membership || {}
46250
- );
46251
- const { client } = useChatContext();
46252
- (0, import_react113.useEffect)(() => {
46253
- if (!channel) return;
46254
- const subscriptions = ["member.updated"].map(
46255
- (v) => client.on(v, () => {
46256
- setMembership(channel.state.membership);
46257
- })
46258
- );
46259
- return () => subscriptions.forEach((subscription) => subscription.unsubscribe());
46260
- }, [client, channel]);
46261
- return membership;
46291
+ var import_shim = require("use-sync-external-store/shim");
46292
+ var noop = () => {
46262
46293
  };
46294
+ function useSelectedChannelState({
46295
+ channel,
46296
+ stateChangeEventKeys = ["all"],
46297
+ selector: selector7
46298
+ }) {
46299
+ const subscribe = (0, import_react113.useCallback)(
46300
+ (onStoreChange) => {
46301
+ if (!channel) return noop;
46302
+ const subscriptions = stateChangeEventKeys.map(
46303
+ (et) => channel.on(et, () => {
46304
+ onStoreChange(selector7(channel));
46305
+ })
46306
+ );
46307
+ return () => subscriptions.forEach((subscription) => subscription.unsubscribe());
46308
+ },
46309
+ [channel, selector7, stateChangeEventKeys]
46310
+ );
46311
+ const getSnapshot = (0, import_react113.useCallback)(() => {
46312
+ if (!channel) return void 0;
46313
+ return selector7(channel);
46314
+ }, [channel, selector7]);
46315
+ return (0, import_shim.useSyncExternalStore)(subscribe, getSnapshot);
46316
+ }
46317
+
46318
+ // src/components/ChannelList/hooks/useChannelMembershipState.ts
46319
+ var selector = (c) => c.state.membership;
46320
+ var keys2 = ["member.updated"];
46321
+ function useChannelMembershipState(channel) {
46322
+ return useSelectedChannelState({ channel, selector, stateChangeEventKeys: keys2 });
46323
+ }
46263
46324
 
46264
46325
  // src/components/ChannelPreview/icons.tsx
46265
46326
  var import_react114 = __toESM(require("react"));
@@ -46744,12 +46805,12 @@ var ThreadAdapter = ({ children }) => {
46744
46805
  useActiveThread({ activeThread });
46745
46806
  return /* @__PURE__ */ import_react122.default.createElement(ThreadProvider, { thread: activeThread }, children);
46746
46807
  };
46747
- var selector = ({ unreadThreadCount }) => ({
46808
+ var selector2 = ({ unreadThreadCount }) => ({
46748
46809
  unreadThreadCount
46749
46810
  });
46750
46811
  var ChatViewSelector = () => {
46751
46812
  const { client } = useChatContext();
46752
- const { unreadThreadCount } = useStateStore(client.threads.state, selector);
46813
+ const { unreadThreadCount } = useStateStore(client.threads.state, selector2);
46753
46814
  const { activeChatView, setActiveChatView } = (0, import_react122.useContext)(ChatViewContext);
46754
46815
  return /* @__PURE__ */ import_react122.default.createElement("div", { className: "str-chat__chat-view__selector" }, /* @__PURE__ */ import_react122.default.createElement(
46755
46816
  "button",
@@ -46811,7 +46872,7 @@ var getTitleFromMessage = ({
46811
46872
  var ThreadListItemUI = (props) => {
46812
46873
  const { client } = useChatContext();
46813
46874
  const thread = useThreadListItemContext();
46814
- const selector6 = (0, import_react123.useCallback)(
46875
+ const selector7 = (0, import_react123.useCallback)(
46815
46876
  (nextValue) => ({
46816
46877
  channel: nextValue.channel,
46817
46878
  deletedAt: nextValue.deletedAt,
@@ -46823,7 +46884,7 @@ var ThreadListItemUI = (props) => {
46823
46884
  );
46824
46885
  const { channel, deletedAt, latestReply, ownUnreadMessageCount, parentMessage } = useStateStore(
46825
46886
  thread.state,
46826
- selector6
46887
+ selector7
46827
46888
  );
46828
46889
  const { displayTitle: channelDisplayTitle } = useChannelPreviewInfo({ channel });
46829
46890
  const { activeThread, setActiveThread } = useThreadsViewContext();
@@ -46860,12 +46921,12 @@ var ThreadListEmptyPlaceholder = () => /* @__PURE__ */ import_react125.default.c
46860
46921
 
46861
46922
  // src/components/Threads/ThreadList/ThreadListUnseenThreadsBanner.tsx
46862
46923
  var import_react126 = __toESM(require("react"));
46863
- var selector2 = (nextValue) => ({
46924
+ var selector3 = (nextValue) => ({
46864
46925
  unseenThreadIds: nextValue.unseenThreadIds
46865
46926
  });
46866
46927
  var ThreadListUnseenThreadsBanner = () => {
46867
46928
  const { client } = useChatContext();
46868
- const { unseenThreadIds } = useStateStore(client.threads.state, selector2);
46929
+ const { unseenThreadIds } = useStateStore(client.threads.state, selector3);
46869
46930
  if (!unseenThreadIds.length) return null;
46870
46931
  return /* @__PURE__ */ import_react126.default.createElement("div", { className: "str-chat__unseen-threads-banner" }, unseenThreadIds.length, " unread threads", /* @__PURE__ */ import_react126.default.createElement(
46871
46932
  "button",
@@ -46879,19 +46940,19 @@ var ThreadListUnseenThreadsBanner = () => {
46879
46940
 
46880
46941
  // src/components/Threads/ThreadList/ThreadListLoadingIndicator.tsx
46881
46942
  var import_react127 = __toESM(require("react"));
46882
- var selector3 = (nextValue) => ({
46943
+ var selector4 = (nextValue) => ({
46883
46944
  isLoadingNext: nextValue.pagination.isLoadingNext
46884
46945
  });
46885
46946
  var ThreadListLoadingIndicator = () => {
46886
46947
  const { LoadingIndicator: LoadingIndicator2 = LoadingIndicator } = useComponentContext();
46887
46948
  const { client } = useChatContext();
46888
- const { isLoadingNext } = useStateStore(client.threads.state, selector3);
46949
+ const { isLoadingNext } = useStateStore(client.threads.state, selector4);
46889
46950
  if (!isLoadingNext) return null;
46890
46951
  return /* @__PURE__ */ import_react127.default.createElement("div", { className: "str-chat__thread-list-loading-indicator" }, /* @__PURE__ */ import_react127.default.createElement(LoadingIndicator2, null));
46891
46952
  };
46892
46953
 
46893
46954
  // src/components/Threads/ThreadList/ThreadList.tsx
46894
- var selector4 = (nextValue) => ({ threads: nextValue.threads });
46955
+ var selector5 = (nextValue) => ({ threads: nextValue.threads });
46895
46956
  var computeItemKey = (_, item) => item.id;
46896
46957
  var useThreadList = () => {
46897
46958
  const { client } = useChatContext();
@@ -46920,7 +46981,7 @@ var ThreadList = ({ virtuosoProps }) => {
46920
46981
  ThreadListLoadingIndicator: ThreadListLoadingIndicator2 = ThreadListLoadingIndicator,
46921
46982
  ThreadListUnseenThreadsBanner: ThreadListUnseenThreadsBanner2 = ThreadListUnseenThreadsBanner
46922
46983
  } = useComponentContext();
46923
- const { threads } = useStateStore(client.threads.state, selector4);
46984
+ const { threads } = useStateStore(client.threads.state, selector5);
46924
46985
  useThreadList();
46925
46986
  return /* @__PURE__ */ import_react128.default.createElement("div", { className: "str-chat__thread-list-container" }, /* @__PURE__ */ import_react128.default.createElement(ThreadListUnseenThreadsBanner2, null), /* @__PURE__ */ import_react128.default.createElement(
46926
46987
  import_react_virtuoso.Virtuoso,
@@ -51138,7 +51199,7 @@ var UnMemoizedChatAutoComplete = (props) => {
51138
51199
  closeCommandsList: messageInput.closeCommandsList,
51139
51200
  closeMentionsList: messageInput.closeMentionsList,
51140
51201
  containerClassName: "str-chat__textarea str-chat__message-textarea-react-host",
51141
- disabled: disabled || !!cooldownRemaining,
51202
+ disabled: (props.disabled ?? disabled) || !!cooldownRemaining,
51142
51203
  disableMentions: messageInput.disableMentions,
51143
51204
  grow: messageInput.grow,
51144
51205
  handleSubmit: props.handleSubmit || messageInput.handleSubmit,
@@ -52386,6 +52447,21 @@ var hasNotMoreMessages = (returnedCountMessages, limit) => returnedCountMessages
52386
52447
  function isDateSeparatorMessage(message) {
52387
52448
  return message.customType === CUSTOM_MESSAGE_TYPE.date && !!message.date && isDate(message.date);
52388
52449
  }
52450
+ var getIsFirstUnreadMessage = ({
52451
+ firstUnreadMessageId,
52452
+ isFirstMessage,
52453
+ lastReadDate,
52454
+ lastReadMessageId,
52455
+ message,
52456
+ previousMessage,
52457
+ unreadMessageCount = 0
52458
+ }) => {
52459
+ const createdAtTimestamp = message.created_at && new Date(message.created_at).getTime();
52460
+ const lastReadTimestamp = lastReadDate?.getTime();
52461
+ const messageIsUnread = !!createdAtTimestamp && !!lastReadTimestamp && createdAtTimestamp > lastReadTimestamp;
52462
+ const previousMessageIsLastRead = !!lastReadMessageId && lastReadMessageId === previousMessage?.id;
52463
+ return firstUnreadMessageId === message.id || !!unreadMessageCount && messageIsUnread && (isFirstMessage || previousMessageIsLastRead);
52464
+ };
52389
52465
 
52390
52466
  // src/components/MessageList/hooks/MessageList/useEnrichedMessages.ts
52391
52467
  var useEnrichedMessages = (args) => {
@@ -52742,7 +52818,6 @@ var useMarkRead = ({
52742
52818
  if (shouldMarkRead(channel.countUnread())) markRead();
52743
52819
  };
52744
52820
  const handleMessageNew = (event) => {
52745
- const newMessageToCurrentChannel = event.cid === channel.cid;
52746
52821
  const isOwnMessage = event.user?.id && event.user.id === client.user?.id;
52747
52822
  const mainChannelUpdated = !event.message?.parent_id || event.message?.show_in_channel;
52748
52823
  if (isOwnMessage) return;
@@ -52760,17 +52835,17 @@ var useMarkRead = ({
52760
52835
  unread_messages: previousUnreadCount + 1
52761
52836
  };
52762
52837
  });
52763
- } else if (newMessageToCurrentChannel && mainChannelUpdated && shouldMarkRead(channel.countUnread())) {
52838
+ } else if (mainChannelUpdated && shouldMarkRead(channel.countUnread())) {
52764
52839
  markRead();
52765
52840
  }
52766
52841
  };
52767
- client.on("message.new", handleMessageNew);
52842
+ channel.on("message.new", handleMessageNew);
52768
52843
  document.addEventListener("visibilitychange", onVisibilityChange);
52769
52844
  const hasScrolledToBottom = previousRenderMessageListScrolledToBottom.current !== isMessageListScrolledToBottom && isMessageListScrolledToBottom;
52770
52845
  if (hasScrolledToBottom && shouldMarkRead(channel.countUnread())) markRead();
52771
52846
  previousRenderMessageListScrolledToBottom.current = isMessageListScrolledToBottom;
52772
52847
  return () => {
52773
- client.off("message.new", handleMessageNew);
52848
+ channel.off("message.new", handleMessageNew);
52774
52849
  document.removeEventListener("visibilitychange", onVisibilityChange);
52775
52850
  };
52776
52851
  }, [
@@ -53205,6 +53280,7 @@ function defaultRenderMessages({
53205
53280
  } = components;
53206
53281
  const renderedMessages = [];
53207
53282
  let firstMessage;
53283
+ let previousMessage = void 0;
53208
53284
  for (let index3 = 0; index3 < messages.length; index3++) {
53209
53285
  const message = messages[index3];
53210
53286
  if (isDateSeparatorMessage(message)) {
@@ -53232,16 +53308,17 @@ function defaultRenderMessages({
53232
53308
  }
53233
53309
  const groupStyles = messageGroupStyles[message.id] || "";
53234
53310
  const messageClass = customClasses?.message || `str-chat__li str-chat__li--${groupStyles}`;
53235
- const createdAtTimestamp = message.created_at && new Date(message.created_at).getTime();
53236
- const lastReadTimestamp = channelUnreadUiState?.last_read.getTime();
53237
- const isFirstMessage = firstMessage?.id && firstMessage.id === message.id;
53238
- const isNewestMessage = index3 === messages.length - 1;
53239
- const isLastReadMessage = channelUnreadUiState?.last_read_message_id === message.id || !channelUnreadUiState?.unread_messages && createdAtTimestamp === lastReadTimestamp;
53240
- const isFirstUnreadMessage = channelUnreadUiState?.first_unread_message_id === message.id || !!channelUnreadUiState?.unread_messages && !!createdAtTimestamp && !!lastReadTimestamp && createdAtTimestamp > lastReadTimestamp && isFirstMessage;
53241
- const showUnreadSeparatorAbove = !channelUnreadUiState?.last_read_message_id && isFirstUnreadMessage;
53242
- const showUnreadSeparatorBelow = isLastReadMessage && !isNewestMessage && (channelUnreadUiState?.first_unread_message_id || !!channelUnreadUiState?.unread_messages);
53311
+ const isFirstUnreadMessage = getIsFirstUnreadMessage({
53312
+ firstUnreadMessageId: channelUnreadUiState?.first_unread_message_id,
53313
+ isFirstMessage: !!firstMessage?.id && firstMessage.id === message.id,
53314
+ lastReadDate: channelUnreadUiState?.last_read,
53315
+ lastReadMessageId: channelUnreadUiState?.last_read_message_id,
53316
+ message,
53317
+ previousMessage,
53318
+ unreadMessageCount: channelUnreadUiState?.unread_messages
53319
+ });
53243
53320
  renderedMessages.push(
53244
- /* @__PURE__ */ import_react245.default.createElement(import_react245.Fragment, { key: message.id || message.created_at }, showUnreadSeparatorAbove && UnreadMessagesSeparator2 && /* @__PURE__ */ import_react245.default.createElement("li", { className: "str-chat__li str-chat__unread-messages-separator-wrapper" }, /* @__PURE__ */ import_react245.default.createElement(UnreadMessagesSeparator2, { unreadCount: channelUnreadUiState?.unread_messages })), /* @__PURE__ */ import_react245.default.createElement("li", { className: messageClass, "data-message-id": message.id, "data-testid": messageClass }, /* @__PURE__ */ import_react245.default.createElement(
53321
+ /* @__PURE__ */ import_react245.default.createElement(import_react245.Fragment, { key: message.id || message.created_at }, isFirstUnreadMessage && UnreadMessagesSeparator2 && /* @__PURE__ */ import_react245.default.createElement("li", { className: "str-chat__li str-chat__unread-messages-separator-wrapper" }, /* @__PURE__ */ import_react245.default.createElement(UnreadMessagesSeparator2, { unreadCount: channelUnreadUiState?.unread_messages })), /* @__PURE__ */ import_react245.default.createElement("li", { className: messageClass, "data-message-id": message.id, "data-testid": messageClass }, /* @__PURE__ */ import_react245.default.createElement(
53245
53322
  Message,
53246
53323
  {
53247
53324
  groupStyles: [groupStyles],
@@ -53250,8 +53327,9 @@ function defaultRenderMessages({
53250
53327
  readBy: readData[message.id] || [],
53251
53328
  ...messageProps
53252
53329
  }
53253
- )), showUnreadSeparatorBelow && UnreadMessagesSeparator2 && /* @__PURE__ */ import_react245.default.createElement("li", { className: "str-chat__li str-chat__unread-messages-separator-wrapper" }, /* @__PURE__ */ import_react245.default.createElement(UnreadMessagesSeparator2, { unreadCount: channelUnreadUiState?.unread_messages })))
53330
+ )))
53254
53331
  );
53332
+ previousMessage = message;
53255
53333
  }
53256
53334
  }
53257
53335
  return renderedMessages;
@@ -53851,15 +53929,16 @@ var messageRenderer = (virtuosoIndex, _data, virtuosoContext) => {
53851
53929
  const maybeNextMessage = messageList[streamMessageIndex + 1];
53852
53930
  const firstOfGroup = shouldGroupByUser && (message.user?.id !== maybePrevMessage?.user?.id || maybePrevMessage && isMessageEdited(maybePrevMessage));
53853
53931
  const endOfGroup = shouldGroupByUser && (message.user?.id !== maybeNextMessage?.user?.id || isMessageEdited(message));
53854
- const createdAtTimestamp = message.created_at && new Date(message.created_at).getTime();
53855
- const lastReadTimestamp = lastReadDate?.getTime();
53856
- const isFirstMessage = streamMessageIndex === 0;
53857
- const isNewestMessage = lastReadMessageId === lastReceivedMessageId;
53858
- const isLastReadMessage = message.id === lastReadMessageId || !unreadMessageCount && createdAtTimestamp === lastReadTimestamp;
53859
- const isFirstUnreadMessage = firstUnreadMessageId === message.id || !!unreadMessageCount && createdAtTimestamp && lastReadTimestamp && createdAtTimestamp > lastReadTimestamp && isFirstMessage;
53860
- const showUnreadSeparatorAbove = !lastReadMessageId && isFirstUnreadMessage;
53861
- const showUnreadSeparatorBelow = isLastReadMessage && !isNewestMessage && (firstUnreadMessageId || !!unreadMessageCount);
53862
- return /* @__PURE__ */ import_react255.default.createElement(import_react255.default.Fragment, null, showUnreadSeparatorAbove && /* @__PURE__ */ import_react255.default.createElement("div", { className: "str-chat__unread-messages-separator-wrapper" }, /* @__PURE__ */ import_react255.default.createElement(UnreadMessagesSeparator2, { unreadCount: unreadMessageCount })), /* @__PURE__ */ import_react255.default.createElement(
53932
+ const isFirstUnreadMessage = getIsFirstUnreadMessage({
53933
+ firstUnreadMessageId,
53934
+ isFirstMessage: streamMessageIndex === 0,
53935
+ lastReadDate,
53936
+ lastReadMessageId,
53937
+ message,
53938
+ previousMessage: streamMessageIndex ? messageList[streamMessageIndex - 1] : void 0,
53939
+ unreadMessageCount
53940
+ });
53941
+ return /* @__PURE__ */ import_react255.default.createElement(import_react255.default.Fragment, null, isFirstUnreadMessage && /* @__PURE__ */ import_react255.default.createElement("div", { className: "str-chat__unread-messages-separator-wrapper" }, /* @__PURE__ */ import_react255.default.createElement(UnreadMessagesSeparator2, { unreadCount: unreadMessageCount })), /* @__PURE__ */ import_react255.default.createElement(
53863
53942
  Message,
53864
53943
  {
53865
53944
  additionalMessageInputProps,
@@ -53882,7 +53961,7 @@ var messageRenderer = (virtuosoIndex, _data, virtuosoContext) => {
53882
53961
  sortReactions,
53883
53962
  threadList
53884
53963
  }
53885
- ), showUnreadSeparatorBelow && /* @__PURE__ */ import_react255.default.createElement("div", { className: "str-chat__unread-messages-separator-wrapper" }, /* @__PURE__ */ import_react255.default.createElement(UnreadMessagesSeparator2, { unreadCount: unreadMessageCount })));
53964
+ ));
53886
53965
  };
53887
53966
 
53888
53967
  // src/components/MessageList/VirtualizedMessageList.tsx
@@ -55359,7 +55438,7 @@ var useChat = ({
55359
55438
  if (!client) return;
55360
55439
  const userAgent = client.getUserAgent();
55361
55440
  if (!userAgent.includes("stream-chat-react")) {
55362
- client.setUserAgent(`stream-chat-react-12.8.1-${userAgent}`);
55441
+ client.setUserAgent(`stream-chat-react-12.9.0-${userAgent}`);
55363
55442
  }
55364
55443
  client.threads.registerSubscriptions();
55365
55444
  client.polls.registerSubscriptions();
@@ -55649,7 +55728,7 @@ var Thread = (props) => {
55649
55728
  /* @__PURE__ */ import_react269.default.createElement(ThreadInner, { ...props, key: `thread-${(thread ?? threadInstance)?.id}-${channel?.cid}` })
55650
55729
  );
55651
55730
  };
55652
- var selector5 = (nextValue) => ({
55731
+ var selector6 = (nextValue) => ({
55653
55732
  isLoadingNext: nextValue.pagination.isLoadingNext,
55654
55733
  isLoadingPrev: nextValue.pagination.isLoadingPrev,
55655
55734
  parentMessage: nextValue.parentMessage,
@@ -55669,7 +55748,7 @@ var ThreadInner = (props) => {
55669
55748
  virtualized
55670
55749
  } = props;
55671
55750
  const threadInstance = useThreadContext();
55672
- const { isLoadingNext, isLoadingPrev, parentMessage, replies } = useStateStore(threadInstance?.state, selector5) ?? {};
55751
+ const { isLoadingNext, isLoadingPrev, parentMessage, replies } = useStateStore(threadInstance?.state, selector6) ?? {};
55673
55752
  const {
55674
55753
  thread,
55675
55754
  threadHasMore,
@@ -55988,6 +56067,7 @@ var Window = import_react270.default.memo(UnMemoizedWindow);
55988
56067
  enTranslations,
55989
56068
  esTranslations,
55990
56069
  escapeRegExp,
56070
+ extractSortValue,
55991
56071
  findLastPinnedChannelIndex,
55992
56072
  frTranslations,
55993
56073
  getChannel,
@@ -55996,6 +56076,7 @@ var Window = import_react270.default.memo(UnMemoizedWindow);
55996
56076
  getGroupChannelDisplayInfo,
55997
56077
  getGroupStyles,
55998
56078
  getImages,
56079
+ getIsFirstUnreadMessage,
55999
56080
  getLastReceived,
56000
56081
  getLatestMessagePreview,
56001
56082
  getMessageActions,