@droppii-org/chat-mobile 0.2.98 → 0.2.100

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.
Files changed (37) hide show
  1. package/lib/module/hooks/conversation/useSingleAccessGuard.js +33 -0
  2. package/lib/module/hooks/conversation/useSingleAccessGuard.js.map +1 -0
  3. package/lib/module/hooks/groups/useGroupAccessGuard.js +26 -17
  4. package/lib/module/hooks/groups/useGroupAccessGuard.js.map +1 -1
  5. package/lib/module/screens/chat-detail/ChatDetail.js +58 -47
  6. package/lib/module/screens/chat-detail/ChatDetail.js.map +1 -1
  7. package/lib/module/screens/chat-detail/ChatListLegend.js +38 -5
  8. package/lib/module/screens/chat-detail/ChatListLegend.js.map +1 -1
  9. package/lib/module/screens/chat-detail/components/ChatDetailLoading.js +38 -0
  10. package/lib/module/screens/chat-detail/components/ChatDetailLoading.js.map +1 -0
  11. package/lib/module/store/message.js +1 -1
  12. package/lib/module/store/message.js.map +1 -1
  13. package/lib/module/utils/conversation.js +21 -0
  14. package/lib/module/utils/conversation.js.map +1 -1
  15. package/lib/module/utils/message.js +2 -3
  16. package/lib/module/utils/message.js.map +1 -1
  17. package/lib/typescript/src/hooks/conversation/useSingleAccessGuard.d.ts +16 -0
  18. package/lib/typescript/src/hooks/conversation/useSingleAccessGuard.d.ts.map +1 -0
  19. package/lib/typescript/src/hooks/groups/useGroupAccessGuard.d.ts +6 -0
  20. package/lib/typescript/src/hooks/groups/useGroupAccessGuard.d.ts.map +1 -1
  21. package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts +2 -2
  22. package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts.map +1 -1
  23. package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts.map +1 -1
  24. package/lib/typescript/src/screens/chat-detail/components/ChatDetailLoading.d.ts +2 -0
  25. package/lib/typescript/src/screens/chat-detail/components/ChatDetailLoading.d.ts.map +1 -0
  26. package/lib/typescript/src/utils/conversation.d.ts +17 -0
  27. package/lib/typescript/src/utils/conversation.d.ts.map +1 -1
  28. package/lib/typescript/src/utils/message.d.ts.map +1 -1
  29. package/package.json +2 -2
  30. package/src/hooks/conversation/useSingleAccessGuard.ts +44 -0
  31. package/src/hooks/groups/useGroupAccessGuard.ts +28 -19
  32. package/src/screens/chat-detail/ChatDetail.tsx +80 -43
  33. package/src/screens/chat-detail/ChatListLegend.tsx +40 -5
  34. package/src/screens/chat-detail/components/ChatDetailLoading.tsx +31 -0
  35. package/src/store/message.ts +1 -1
  36. package/src/utils/conversation.ts +31 -0
  37. package/src/utils/message.ts +6 -3
@@ -1 +1 @@
1
- {"version":3,"names":["create","DeviceEventEmitter","OpenIMSDK","MessageType","ViewType","ChatEvent","mergeMessages","isMessageRevoked","useConversationStore","PAGE_SIZE","useMessageStore","set","get","messages","hasMoreOld","hasMoreNew","initLoading","moreOldLoading","moreNewLoading","setMessages","hasMore","pushNewMessage","message","state","updateOneMessage","tmpList","idx","findIndex","msg","clientMsgID","deleteOneMessage","filter","getMoreOldMessages","loadMore","applicationType","conversationId","params","count","startClientMsgID","conversationID","viewType","History","res","getAdvancedHistoryMessageListApp","getState","currentConversationId","messageList","isEnd","error","console","log","getMoreNewMessages","length","getAdvancedHistoryMessageListReverseApp","Promise","resolve","setTimeout","emit","ScrollToBottom","searchMessages","startClientMsgId","searchPrevParams","Search","searchNextParams","searchCurrentParams","clientMsgIDList","findMessageList","searchPrevRes","searchNextRes","currentMessages","findResultItems","find","item","newMessages","targetMessage","TargetMessageUnavailable","ScrollToMessage","clientMessageId","reset","markMessageRevoked","alreadyRevoked","some","contentType","RevokeMessage","MessageRevoked","revokeQuotedReferences","forEach","quoteElem","quoteMessage","atTextElem"],"sourceRoot":"../../../src","sources":["store/message.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["create","DeviceEventEmitter","OpenIMSDK","MessageType","ViewType","ChatEvent","mergeMessages","isMessageRevoked","useConversationStore","PAGE_SIZE","useMessageStore","set","get","messages","hasMoreOld","hasMoreNew","initLoading","moreOldLoading","moreNewLoading","setMessages","hasMore","pushNewMessage","message","state","updateOneMessage","tmpList","idx","findIndex","msg","clientMsgID","deleteOneMessage","filter","getMoreOldMessages","loadMore","applicationType","conversationId","params","count","startClientMsgID","conversationID","viewType","History","res","getAdvancedHistoryMessageListApp","getState","currentConversationId","messageList","isEnd","error","console","log","getMoreNewMessages","length","getAdvancedHistoryMessageListReverseApp","Promise","resolve","setTimeout","emit","ScrollToBottom","searchMessages","startClientMsgId","searchPrevParams","Search","searchNextParams","searchCurrentParams","clientMsgIDList","findMessageList","searchPrevRes","searchNextRes","currentMessages","findResultItems","find","item","newMessages","targetMessage","TargetMessageUnavailable","ScrollToMessage","clientMessageId","reset","markMessageRevoked","alreadyRevoked","some","contentType","RevokeMessage","MessageRevoked","revokeQuotedReferences","forEach","quoteElem","quoteMessage","atTextElem"],"sourceRoot":"../../../src","sources":["store/message.ts"],"mappings":"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","ignoreList":[]}
@@ -36,4 +36,25 @@ export const getBotId = conversation => {
36
36
  export const isGroupConversation = conversation => {
37
37
  return conversation?.peerType === PeerType.Group;
38
38
  };
39
+ const GROUP_CONVERSATION_ID_PREFIX = 'sg_';
40
+
41
+ /**
42
+ * Group conversationIds are formatted as "sg_<groupID>" — derive the groupID
43
+ * straight from the id when a full ConversationItem isn't available yet (e.g.
44
+ * a non-member previewing a public group via deeplink has no synced
45
+ * conversation object to read groupID off of).
46
+ */
47
+ export const getGroupIdFromConversationId = conversationId => conversationId?.startsWith(GROUP_CONVERSATION_ID_PREFIX) ? conversationId.slice(GROUP_CONVERSATION_ID_PREFIX.length) : '';
48
+ const SINGLE_CONVERSATION_ID_PREFIX = 'si_';
49
+ export const isSingleConversationId = conversationId => conversationId.startsWith(SINGLE_CONVERSATION_ID_PREFIX);
50
+
51
+ /**
52
+ * A 1v1 conversationId is "si_<userA>_<userB>" (see `getConversationID`), with
53
+ * no fixed order between the two — same as the forward/reverse match
54
+ * `isSameConversation` does above. Used to tell whether the logged-in user is
55
+ * actually a participant when no local conversation record has synced (e.g. a
56
+ * deeplink into a 1v1 the current account has no access to). Only meaningful
57
+ * once `isSingleConversationId` is true.
58
+ */
59
+ export const isConversationParticipant = (conversationId, userId) => !!userId && conversationId.split('_').includes(userId);
39
60
  //# sourceMappingURL=conversation.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["PeerType","SessionType","conversationCompare","a","b","isPinned","aCompare","draftTextTime","latestMsgSendTime","bCompare","getConversationID","sessionType","senderID","receiverID","prefix","Single","Notification","filter","Boolean","join","sortConversation","map","list","Object","keys","id","isNotInGroup","sort","getBotId","conversation","peerType","Bot","JSON","parse","ex","sessionInfo","data","botId","_","undefined","isGroupConversation","Group"],"sourceRoot":"../../../src","sources":["utils/conversation.ts"],"mappings":";;AAAA,SACEA,QAAQ,EACRC,WAAW,QAEN,+BAA+B;AAEtC,OAAO,MAAMC,mBAAmB,GAAGA,CACjCC,CAAmB,EACnBC,CAAmB,KAChB;EACH,IAAID,CAAC,CAACE,QAAQ,KAAKD,CAAC,CAACC,QAAQ,EAAE,OAAOF,CAAC,CAACE,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC;EAEzD,MAAMC,QAAQ,GACZH,CAAC,CAACI,aAAa,GAAGJ,CAAC,CAACK,iBAAiB,GACjCL,CAAC,CAACI,aAAa,GACfJ,CAAC,CAACK,iBAAiB;EACzB,MAAMC,QAAQ,GACZL,CAAC,CAACG,aAAa,GAAGH,CAAC,CAACI,iBAAiB,GACjCJ,CAAC,CAACG,aAAa,GACfH,CAAC,CAACI,iBAAiB;EAEzB,OAAOC,QAAQ,GAAGH,QAAQ;AAC5B,CAAC;AAED,OAAO,MAAMI,iBAAiB,GAAGA,CAC/BC,WAAwB,EACxBC,QAAiB,EACjBC,UAAmB,KAChB;EACH,MAAMC,MAAM,GACVH,WAAW,KAAKV,WAAW,CAACc,MAAM,GAC9B,IAAI,GACJJ,WAAW,KAAKV,WAAW,CAACe,YAAY,GACtC,IAAI,GACJ,IAAI;EAEZ,OAAO,CAACF,MAAM,EAAEF,QAAQ,EAAEC,UAAU,CAAC,CAACI,MAAM,CAACC,OAAO,CAAC,CAACC,IAAI,CAAC,GAAG,CAAC;AACjE,CAAC;AAED,OAAO,MAAMC,gBAAgB,GAAIC,GAAqC,IAAK;EACzE;EACA;EACA;EACA,MAAMC,IAAI,GAAGC,MAAM,CAACC,IAAI,CAACH,GAAG,CAAC,CAC1BJ,MAAM,CAAEQ,EAAE,IAAK,CAACJ,GAAG,CAACI,EAAE,CAAC,EAAEC,YAAY,CAAC,CACtCC,IAAI,CAAC,CAACxB,CAAC,EAAEC,CAAC,KAAKF,mBAAmB,CAACmB,GAAG,CAAClB,CAAC,CAAC,EAAGkB,GAAG,CAACjB,CAAC,CAAE,CAAC,CAAC;EACxD,OAAO;IAAEiB,GAAG;IAAEC;EAAK,CAAC;AACtB,CAAC;AAED,OAAO,MAAMM,QAAQ,GAAIC,YAA+B,IAAK;EAC3D,IAAIA,YAAY,IAAIA,YAAY,EAAEC,QAAQ,KAAK9B,QAAQ,CAAC+B,GAAG,EAAE;IAC3D,IAAI;MACF,MAAMN,EAAE,GAAGO,IAAI,CAACC,KAAK,CAACJ,YAAY,EAAEK,EAAE,IAAI,IAAI,CAAC,EAAEC,WAAW,EAAEC,IAAI,EAAEC,KAAK;MACzE,OAAOZ,EAAE;MACT;IACF,CAAC,CAAC,OAAOa,CAAM,EAAE;MACf,OAAOC,SAAS;IAClB;EACF;EACA,OAAOA,SAAS;AAClB,CAAC;AAED,OAAO,MAAMC,mBAAmB,GAC9BX,YAAsE,IACnE;EACH,OAAOA,YAAY,EAAEC,QAAQ,KAAK9B,QAAQ,CAACyC,KAAK;AAClD,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["PeerType","SessionType","conversationCompare","a","b","isPinned","aCompare","draftTextTime","latestMsgSendTime","bCompare","getConversationID","sessionType","senderID","receiverID","prefix","Single","Notification","filter","Boolean","join","sortConversation","map","list","Object","keys","id","isNotInGroup","sort","getBotId","conversation","peerType","Bot","JSON","parse","ex","sessionInfo","data","botId","_","undefined","isGroupConversation","Group","GROUP_CONVERSATION_ID_PREFIX","getGroupIdFromConversationId","conversationId","startsWith","slice","length","SINGLE_CONVERSATION_ID_PREFIX","isSingleConversationId","isConversationParticipant","userId","split","includes"],"sourceRoot":"../../../src","sources":["utils/conversation.ts"],"mappings":"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","ignoreList":[]}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  import { PeerType, SessionType } from '@droppii/openim-rn-client-sdk';
4
- import { getConversationID } from "./conversation.js";
4
+ import { getConversationID, getGroupIdFromConversationId } from "./conversation.js";
5
5
 
6
6
  /**
7
7
  * Canonical timestamp for a message. `sendTime` is 0 until the SDK stamps an
@@ -90,8 +90,7 @@ export const getReceiverId = conversation => {
90
90
  recvID: ''
91
91
  };
92
92
  if (conversation.peerType === PeerType.Group) {
93
- // Group conversation: groupID is embedded after the "sg_" prefix
94
- const groupID = conversation.groupID || conversation.conversationID.slice(3);
93
+ const groupID = conversation.groupID || getGroupIdFromConversationId(conversation.conversationID);
95
94
  return {
96
95
  groupID: groupID ?? '',
97
96
  recvID: ''
@@ -1 +1 @@
1
- {"version":3,"names":["PeerType","SessionType","getConversationID","getMessageTime","message","sendTime","createTime","getMessageKey","clientMsgID","serverMsgID","getMessageRenderId","index","mergeMessages","current","incoming","map","Map","key","set","Array","from","values","sort","a","b","normalizeCreatedMessage","normalized","JSON","parse","Error","resolveHistoryLastMinSeq","history","fallbackMessage","lastMinSeq","seq","getHistoryPaginationAnchor","messages","length","oldest","reduce","prev","curr","hasNewHistoryMessages","currentKeys","Set","filter","Boolean","some","has","belongsToConversation","conversationId","targetUserId","sessionType","Single","forwardId","sendID","recvID","reverseId","Group","groupID","getReceiverId","conversation","peerType","conversationID","slice","userID"],"sourceRoot":"../../../src","sources":["utils/message.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["PeerType","SessionType","getConversationID","getGroupIdFromConversationId","getMessageTime","message","sendTime","createTime","getMessageKey","clientMsgID","serverMsgID","getMessageRenderId","index","mergeMessages","current","incoming","map","Map","key","set","Array","from","values","sort","a","b","normalizeCreatedMessage","normalized","JSON","parse","Error","resolveHistoryLastMinSeq","history","fallbackMessage","lastMinSeq","seq","getHistoryPaginationAnchor","messages","length","oldest","reduce","prev","curr","hasNewHistoryMessages","currentKeys","Set","filter","Boolean","some","has","belongsToConversation","conversationId","targetUserId","sessionType","Single","forwardId","sendID","recvID","reverseId","Group","groupID","getReceiverId","conversation","peerType","conversationID","userID"],"sourceRoot":"../../../src","sources":["utils/message.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,16 @@
1
+ type Params = {
2
+ conversationId: string;
3
+ currentUserId?: string;
4
+ /** Navigate away from the chat screen. Called once, after the block modal. */
5
+ onBlocked: () => void;
6
+ };
7
+ /**
8
+ * 1v1 conversations have no membership guard of their own — a deeplink into a
9
+ * 1v1 the logged-in account isn't part of never syncs a local conversation
10
+ * record, so this can't rely on a synced `ConversationItem` and instead reads
11
+ * the participant ids straight off the "si_<userA>_<userB>" conversationId.
12
+ * No-ops for anything that isn't a 1v1 conversationId.
13
+ */
14
+ export declare const useSingleAccessGuard: ({ conversationId, currentUserId, onBlocked, }: Params) => void;
15
+ export {};
16
+ //# sourceMappingURL=useSingleAccessGuard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSingleAccessGuard.d.ts","sourceRoot":"","sources":["../../../../../src/hooks/conversation/useSingleAccessGuard.ts"],"names":[],"mappings":"AAOA,KAAK,MAAM,GAAG;IACZ,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAAI,+CAIlC,MAAM,SAkBR,CAAC"}
@@ -1,3 +1,9 @@
1
+ /**
2
+ * The "you can't open this conversation" modal — shared by the group
3
+ * non-member guard and the 1v1 non-participant check in ChatDetail, so both
4
+ * present the exact same blocked experience.
5
+ */
6
+ export declare const showAccessBlockedModal: (onAcknowledge: () => void) => void;
1
7
  type Params = {
2
8
  groupID?: string;
3
9
  /** Navigate away from the chat screen. Called once, after the block modal. */
@@ -1 +1 @@
1
- {"version":3,"file":"useGroupAccessGuard.d.ts","sourceRoot":"","sources":["../../../../../src/hooks/groups/useGroupAccessGuard.ts"],"names":[],"mappings":"AA2CA,KAAK,MAAM,GAAG;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,wBAAwB,MAAM;;CA0IjE,CAAC"}
1
+ {"version":3,"file":"useGroupAccessGuard.d.ts","sourceRoot":"","sources":["../../../../../src/hooks/groups/useGroupAccessGuard.ts"],"names":[],"mappings":"AAyBA;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GAAI,eAAe,MAAM,IAAI,SAoB/D,CAAC;AAoBF,KAAK,MAAM,GAAG;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,wBAAwB,MAAM;;CAwHjE,CAAC"}
@@ -1,4 +1,4 @@
1
1
  import type { ChatDetailProps } from './types';
2
- declare const _default: (props: ChatDetailProps) => import("react").JSX.Element;
3
- export default _default;
2
+ declare const SdkReadyGate: (props: ChatDetailProps) => import("react").JSX.Element;
3
+ export default SdkReadyGate;
4
4
  //# sourceMappingURL=ChatDetail.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChatDetail.d.ts","sourceRoot":"","sources":["../../../../../src/screens/chat-detail/ChatDetail.tsx"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBAuQ/B,OAAO,eAAe;AAAtC,wBAkCE"}
1
+ {"version":3,"file":"ChatDetail.d.ts","sourceRoot":"","sources":["../../../../../src/screens/chat-detail/ChatDetail.tsx"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAmU/C,QAAA,MAAM,YAAY,GAAI,OAAO,eAAe,gCAS3C,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ChatListLegend.d.ts","sourceRoot":"","sources":["../../../../../src/screens/chat-detail/ChatListLegend.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAQf,OAAiB,EAKf,KAAK,WAAW,EACjB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EACL,KAAK,aAAa,EAEnB,MAAM,8BAA8B,CAAC;AActC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAyE7C,UAAU,2BAA4B,SAAQ,aAAa;IACzD,OAAO,EAAE,SAAS,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IACzC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC7B,kBAAkB,EAAE,CAAC,IAAI,EAAE;QACzB,QAAQ,EAAE,OAAO,CAAC;QAClB,aAAa,EAAE,OAAO,CAAC;KACxB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,cAAc,6QAkBtB,2BAA2B,iCAi0B/B,CAAC"}
1
+ {"version":3,"file":"ChatListLegend.d.ts","sourceRoot":"","sources":["../../../../../src/screens/chat-detail/ChatListLegend.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAQf,OAAiB,EAKf,KAAK,WAAW,EACjB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EACL,KAAK,aAAa,EAEnB,MAAM,8BAA8B,CAAC;AActC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAmF7C,UAAU,2BAA4B,SAAQ,aAAa;IACzD,OAAO,EAAE,SAAS,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IACzC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC7B,kBAAkB,EAAE,CAAC,IAAI,EAAE;QACzB,QAAQ,EAAE,OAAO,CAAC;QAClB,aAAa,EAAE,OAAO,CAAC;KACxB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,cAAc,6QAkBtB,2BAA2B,iCA01B/B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const ChatDetailLoading: () => import("react").JSX.Element;
2
+ //# sourceMappingURL=ChatDetailLoading.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatDetailLoading.d.ts","sourceRoot":"","sources":["../../../../../../src/screens/chat-detail/components/ChatDetailLoading.tsx"],"names":[],"mappings":"AAIA,eAAO,MAAM,iBAAiB,mCA0B7B,CAAC"}
@@ -7,4 +7,21 @@ export declare const sortConversation: (map: Record<string, ConversationItem>) =
7
7
  };
8
8
  export declare const getBotId: (conversation?: ConversationItem) => any;
9
9
  export declare const isGroupConversation: (conversation?: Pick<ConversationItem, "conversationType" | "peerType">) => boolean;
10
+ /**
11
+ * Group conversationIds are formatted as "sg_<groupID>" — derive the groupID
12
+ * straight from the id when a full ConversationItem isn't available yet (e.g.
13
+ * a non-member previewing a public group via deeplink has no synced
14
+ * conversation object to read groupID off of).
15
+ */
16
+ export declare const getGroupIdFromConversationId: (conversationId?: string) => string;
17
+ export declare const isSingleConversationId: (conversationId: string) => boolean;
18
+ /**
19
+ * A 1v1 conversationId is "si_<userA>_<userB>" (see `getConversationID`), with
20
+ * no fixed order between the two — same as the forward/reverse match
21
+ * `isSameConversation` does above. Used to tell whether the logged-in user is
22
+ * actually a participant when no local conversation record has synced (e.g. a
23
+ * deeplink into a 1v1 the current account has no access to). Only meaningful
24
+ * once `isSingleConversationId` is true.
25
+ */
26
+ export declare const isConversationParticipant: (conversationId: string, userId?: string) => boolean;
10
27
  //# sourceMappingURL=conversation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../../../src/utils/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EACX,KAAK,gBAAgB,EACtB,MAAM,+BAA+B,CAAC;AAEvC,eAAO,MAAM,mBAAmB,GAC9B,GAAG,gBAAgB,EACnB,GAAG,gBAAgB,WAcpB,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,aAAa,WAAW,EACxB,WAAW,MAAM,EACjB,aAAa,MAAM,WAUpB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC;;;CAQrE,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,eAAe,gBAAgB,QAWvD,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,eAAe,IAAI,CAAC,gBAAgB,EAAE,kBAAkB,GAAG,UAAU,CAAC,YAGvE,CAAC"}
1
+ {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../../../src/utils/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EACX,KAAK,gBAAgB,EACtB,MAAM,+BAA+B,CAAC;AAEvC,eAAO,MAAM,mBAAmB,GAC9B,GAAG,gBAAgB,EACnB,GAAG,gBAAgB,WAcpB,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,aAAa,WAAW,EACxB,WAAW,MAAM,EACjB,aAAa,MAAM,WAUpB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC;;;CAQrE,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,eAAe,gBAAgB,QAWvD,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,eAAe,IAAI,CAAC,gBAAgB,EAAE,kBAAkB,GAAG,UAAU,CAAC,YAGvE,CAAC;AAIF;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,GAAI,iBAAiB,MAAM,WAG5D,CAAC;AAIT,eAAO,MAAM,sBAAsB,GAAI,gBAAgB,MAAM,KAAG,OACN,CAAC;AAE3D;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,GACpC,gBAAgB,MAAM,EACtB,SAAS,MAAM,KACd,OAAiE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../../src/utils/message.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EACjB,MAAM,+BAA+B,CAAC;AAGvC;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,SAAS,WAAW,WACN,CAAC;AAK9C;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,WAAW,EAAE,OAAO,MAAM,WACA,CAAC;AAEvE,eAAO,MAAM,aAAa,GACxB,SAAS,WAAW,EAAE,EACtB,UAAU,WAAW,EAAE,KACtB,WAAW,EAab,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,SAAS,WAAW,GAAG,MAAM,KAC5B,WAYF,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,SAAS;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,EAChC,kBAAkB,WAAW,KAC5B,MAMF,CAAC;AAEF,eAAO,MAAM,0BAA0B,GACrC,UAAU,WAAW,EAAE,KACtB,uBAAuB,GAAG,IAkB5B,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,SAAS,WAAW,EAAE,EACtB,UAAU,WAAW,EAAE,KACtB,OASF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,SAAS,WAAW,EACpB,iBAAiB,MAAM,EACvB,eAAe,MAAM,KACpB,OA2BF,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,eAAe,gBAAgB;;;CAW5D,CAAC"}
1
+ {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../../src/utils/message.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EACjB,MAAM,+BAA+B,CAAC;AAMvC;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,SAAS,WAAW,WACN,CAAC;AAK9C;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,WAAW,EAAE,OAAO,MAAM,WACA,CAAC;AAEvE,eAAO,MAAM,aAAa,GACxB,SAAS,WAAW,EAAE,EACtB,UAAU,WAAW,EAAE,KACtB,WAAW,EAab,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,SAAS,WAAW,GAAG,MAAM,KAC5B,WAYF,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,SAAS;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,EAChC,kBAAkB,WAAW,KAC5B,MAMF,CAAC;AAEF,eAAO,MAAM,0BAA0B,GACrC,UAAU,WAAW,EAAE,KACtB,uBAAuB,GAAG,IAkB5B,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,SAAS,WAAW,EAAE,EACtB,UAAU,WAAW,EAAE,KACtB,OASF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,SAAS,WAAW,EACpB,iBAAiB,MAAM,EACvB,eAAe,MAAM,KACpB,OA2BF,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,eAAe,gBAAgB;;;CAW5D,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@droppii-org/chat-mobile",
3
- "version": "0.2.98",
3
+ "version": "0.2.100",
4
4
  "description": "Droppii chat mobile",
5
5
  "keywords": [
6
6
  "react-native",
@@ -69,7 +69,7 @@
69
69
  "example-legacy": "yarn workspace @droppii-org/chat-mobile-example-legacy"
70
70
  },
71
71
  "dependencies": {
72
- "@droppii/openim-rn-client-sdk": "git+ssh://git@github.com/droppii/open-im-sdk-reactnative.git#v1.0.0-rc39",
72
+ "@droppii/openim-rn-client-sdk": "git+ssh://git@github.com/droppii/open-im-sdk-reactnative.git#v1.0.0-rc40",
73
73
  "@legendapp/list": "^3.3.10",
74
74
  "axios": "^1.16.1",
75
75
  "lodash": "^4.18.1",
@@ -0,0 +1,44 @@
1
+ import { useEffect, useRef } from 'react';
2
+ import {
3
+ isConversationParticipant,
4
+ isSingleConversationId,
5
+ } from '../../utils/conversation';
6
+ import { showAccessBlockedModal } from '../groups/useGroupAccessGuard';
7
+
8
+ type Params = {
9
+ conversationId: string;
10
+ currentUserId?: string;
11
+ /** Navigate away from the chat screen. Called once, after the block modal. */
12
+ onBlocked: () => void;
13
+ };
14
+
15
+ /**
16
+ * 1v1 conversations have no membership guard of their own — a deeplink into a
17
+ * 1v1 the logged-in account isn't part of never syncs a local conversation
18
+ * record, so this can't rely on a synced `ConversationItem` and instead reads
19
+ * the participant ids straight off the "si_<userA>_<userB>" conversationId.
20
+ * No-ops for anything that isn't a 1v1 conversationId.
21
+ */
22
+ export const useSingleAccessGuard = ({
23
+ conversationId,
24
+ currentUserId,
25
+ onBlocked,
26
+ }: Params) => {
27
+ const hasBlockedRef = useRef(false);
28
+ const onBlockedRef = useRef(onBlocked);
29
+ onBlockedRef.current = onBlocked;
30
+
31
+ useEffect(() => {
32
+ hasBlockedRef.current = false;
33
+ }, [conversationId]);
34
+
35
+ useEffect(() => {
36
+ if (!isSingleConversationId(conversationId)) return;
37
+ if (!currentUserId) return;
38
+ if (isConversationParticipant(conversationId, currentUserId)) return;
39
+ if (hasBlockedRef.current) return;
40
+ hasBlockedRef.current = true;
41
+
42
+ showAccessBlockedModal(() => onBlockedRef.current());
43
+ }, [conversationId, currentUserId]);
44
+ };
@@ -23,6 +23,33 @@ type GroupAccessState =
23
23
 
24
24
  type EvaluationResult = { state: Exclude<GroupAccessState, 'checking'> };
25
25
 
26
+ /**
27
+ * The "you can't open this conversation" modal — shared by the group
28
+ * non-member guard and the 1v1 non-participant check in ChatDetail, so both
29
+ * present the exact same blocked experience.
30
+ */
31
+ export const showAccessBlockedModal = (onAcknowledge: () => void) => {
32
+ UIUtils.alert.open({
33
+ title: trans('group:access_blocked_title'),
34
+ message: trans('group:access_blocked_desc'),
35
+ primaryIndex: 0,
36
+ buttonType: 'horizontal-button',
37
+ // Drop any alert raised while this one is up rather than stacking it —
38
+ // OnGroupDismissed fires twice for the group owner.
39
+ ignoreStack: true,
40
+ // Force an acknowledgement: dismissing by tapping outside would leave the
41
+ // user sitting in a conversation they cannot access.
42
+ touchOutsideToDismiss: false,
43
+ buttons: [
44
+ {
45
+ label: trans('group:access_blocked_button'),
46
+ kind: 'primary',
47
+ onPress: onAcknowledge,
48
+ },
49
+ ],
50
+ });
51
+ };
52
+
26
53
  /**
27
54
  * Resolves whether the current user may open `groupID`, per the group-access
28
55
  * spec: private non-members and dismissed groups are blocked outright, while
@@ -74,25 +101,7 @@ export const useGroupAccessGuard = ({ groupID, onBlocked }: Params) => {
74
101
  hasBlockedRef.current = true;
75
102
 
76
103
  setAccessState('blocked');
77
- UIUtils.alert.open({
78
- title: trans('group:access_blocked_title'),
79
- message: trans('group:access_blocked_desc'),
80
- primaryIndex: 0,
81
- buttonType: 'horizontal-button',
82
- // Drop any alert raised while this one is up rather than stacking it —
83
- // OnGroupDismissed fires twice for the group owner.
84
- ignoreStack: true,
85
- // Force an acknowledgement: dismissing by tapping outside would leave the
86
- // user sitting in a conversation they cannot access.
87
- touchOutsideToDismiss: false,
88
- buttons: [
89
- {
90
- label: trans('group:access_blocked_button'),
91
- kind: 'primary',
92
- onPress: () => onBlockedRef.current(),
93
- },
94
- ],
95
- });
104
+ showAccessBlockedModal(() => onBlockedRef.current());
96
105
  }, []);
97
106
 
98
107
  const applyResult = useCallback(
@@ -1,10 +1,10 @@
1
1
  import { memo, useCallback, useEffect, useRef } from 'react';
2
- import { ActivityIndicator, DeviceEventEmitter } from 'react-native';
2
+ import { DeviceEventEmitter } from 'react-native';
3
3
 
4
4
  import { useKeyboardScrollToEnd } from '@legendapp/list/keyboard';
5
5
  import type { LegendListRef } from '@legendapp/list/react-native';
6
6
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
7
- import { KColors, KContainer, KNavigation } from '@droppii/libs';
7
+ import { KContainer } from '@droppii/libs';
8
8
  import { useNavigation, useRoute } from '@react-navigation/native';
9
9
  import { usePinMessage } from '../../hooks/message/usePinMessage';
10
10
  import { PinnedMessageBar } from './PinnedMessageBar';
@@ -32,6 +32,7 @@ import type {
32
32
  import {
33
33
  useGetConversationDetail,
34
34
  useGetConversationTarget,
35
+ useSyncConversationById,
35
36
  } from '../../hooks/conversation/useGetConversationDetail';
36
37
  import {
37
38
  GroupJoinSource,
@@ -42,15 +43,25 @@ import { ChatEvent } from '../../types/events';
42
43
  import { useSetIsShowFLashMessage } from '../../context/global';
43
44
  import { useJoinGroup } from '../../hooks/groups/useJoinGroup';
44
45
  import { useGroupAccessGuard } from '../../hooks/groups/useGroupAccessGuard';
46
+ import { useSingleAccessGuard } from '../../hooks/conversation/useSingleAccessGuard';
47
+ import { useIsJoinedGroup } from '../../hooks/useIsJoinedGroup';
45
48
  import { UIUtils } from '../../utils/UIUtils';
46
49
  import { trans } from '../../translation';
50
+ import { getGroupIdFromConversationId } from '../../utils/conversation';
51
+ import { ChatDetailLoading } from './components/ChatDetailLoading';
52
+
53
+ interface ChatDetailScreenProps extends Omit<
54
+ ChatDetailProps,
55
+ 'targetConversationId' | 'targetBotId'
56
+ > {
57
+ conversationId: string;
58
+ }
47
59
 
48
60
  const ChatDetail = memo(
49
61
  ({
50
- targetConversationId = '',
62
+ conversationId,
51
63
  targetUserId = '',
52
64
  targetGroupId = '',
53
- targetBotId = '',
54
65
  targetMessageId = '',
55
66
  showAddMember,
56
67
  onBack,
@@ -61,20 +72,12 @@ const ChatDetail = memo(
61
72
  customMessageItemFactory,
62
73
  pannelActions,
63
74
  groupJoinSource,
64
- }: ChatDetailProps) => {
75
+ }: ChatDetailScreenProps) => {
65
76
  const navigation = useNavigation();
66
77
  const mediaViewerRef = useRef<MediaViewerModalHandle>(null);
67
78
  const messageToolboxRef = useRef<MessageToolboxRef>(null);
68
79
  const currentUser = useUserStore((s) => s.user);
69
80
 
70
- const { conversationId, isLoading: isLoadingConversation } =
71
- useGetConversationDetail({
72
- targetConversationId,
73
- targetUserId,
74
- targetGroupId,
75
- targetBotId,
76
- });
77
-
78
81
  const conversation = useConversation(conversationId);
79
82
 
80
83
  const { data: target } = useGetConversationTarget(conversationId);
@@ -134,7 +137,16 @@ const ChatDetail = memo(
134
137
  }, [onBack, handleBackDefault]);
135
138
 
136
139
  const { isCheckingAccess } = useGroupAccessGuard({
137
- groupID: conversation?.groupID || targetGroupId,
140
+ groupID:
141
+ conversation?.groupID ||
142
+ targetGroupId ||
143
+ getGroupIdFromConversationId(conversationId),
144
+ onBlocked: handleAccessBlocked,
145
+ });
146
+
147
+ useSingleAccessGuard({
148
+ conversationId,
149
+ currentUserId: currentUser?.userID,
138
150
  onBlocked: handleAccessBlocked,
139
151
  });
140
152
 
@@ -247,7 +259,7 @@ const ChatDetail = memo(
247
259
  messages={messages}
248
260
  conversationId={conversationId}
249
261
  customMessageItemFactory={customMessageItemFactory}
250
- isLoading={initLoading || isLoadingConversation || isCheckingAccess}
262
+ isLoading={initLoading || isCheckingAccess}
251
263
  onLoadMoreOld={getMoreOldMessages}
252
264
  hasMoreOld={hasMoreOld}
253
265
  moreOldLoading={moreOldLoading}
@@ -285,38 +297,63 @@ const ChatDetail = memo(
285
297
  }
286
298
  );
287
299
 
288
- export default (props: ChatDetailProps) => {
289
- const isUserLoaded = useUserStore((s) => s.user != null);
300
+ // Resolve conversation/group/join-status data before ChatDetail mounts, so the
301
+ // header and composer never render with an incomplete or stale group-membership
302
+ // state on a cold-start deeplink open (DROPPII-30942).
303
+ const ConversationDataGate = (props: ChatDetailProps) => {
304
+ const { targetConversationId, targetUserId, targetGroupId, targetBotId } =
305
+ props;
306
+
307
+ const hasTarget = !!(
308
+ targetConversationId ||
309
+ targetUserId ||
310
+ targetGroupId ||
311
+ targetBotId
312
+ );
313
+
314
+ const { conversationId, isLoading: isLoadingConversation } =
315
+ useGetConversationDetail({
316
+ targetConversationId,
317
+ targetUserId,
318
+ targetGroupId:
319
+ targetGroupId || getGroupIdFromConversationId(targetConversationId),
320
+ targetBotId,
321
+ });
322
+
323
+ const conversation = useConversation(conversationId);
324
+ const { isFetching: isSyncingConversation, isFetched: isConversationSynced } =
325
+ useSyncConversationById(conversationId, !!conversation);
326
+
327
+ const { isLoading: isCheckingJoinStatus } = useIsJoinedGroup(
328
+ conversation?.groupID
329
+ );
330
+
331
+ const isConversationResolved =
332
+ !!conversationId &&
333
+ (!!conversation || (isConversationSynced && !isSyncingConversation));
290
334
 
291
- const navigation = useNavigation();
335
+ const isReady =
336
+ !hasTarget ||
337
+ (!isLoadingConversation &&
338
+ isConversationResolved &&
339
+ (!conversation?.groupID || !isCheckingJoinStatus));
340
+
341
+ if (!isReady) {
342
+ return <ChatDetailLoading />;
343
+ }
344
+
345
+ return <ChatDetail {...props} conversationId={conversationId} />;
346
+ };
347
+
348
+ const SdkReadyGate = (props: ChatDetailProps) => {
349
+ const isUserLoaded = useUserStore((s) => s.user != null);
292
350
 
293
351
  // Handle sdk not loaded yet when navigate using deeplink
294
352
  if (!isUserLoaded) {
295
- return (
296
- <KContainer.Page flex edges={['bottom']}>
297
- <KNavigation.Header
298
- theme="light"
299
- alignment="left"
300
- size="small"
301
- disableCenterSpace
302
- shadow
303
- leftButton={{
304
- id: 'back',
305
- icon: {
306
- size: 24,
307
- vectorName: 'arrow-left-o',
308
- vectorProvider: 'DroppiiNew',
309
- tintColor: KColors.primary.normal,
310
- },
311
- onPress: navigation.goBack,
312
- }}
313
- />
314
- <KContainer.View flex center>
315
- <ActivityIndicator size="small" color={KColors.primary.normal} />
316
- </KContainer.View>
317
- </KContainer.Page>
318
- );
353
+ return <ChatDetailLoading />;
319
354
  }
320
355
 
321
- return <ChatDetail {...props} />;
356
+ return <ConversationDataGate {...props} />;
322
357
  };
358
+
359
+ export default SdkReadyGate;
@@ -103,6 +103,16 @@ const FOLLOW_SETTLE_MS = 200;
103
103
  // and the last message stays behind the keyboard.
104
104
  const FOLLOW_TAIL_FRAMES = 3;
105
105
 
106
+ // How long after a new message the list keeps re-anchoring to the end as the
107
+ // content settles. A row's real height is not known when the message is
108
+ // inserted — LegendList still has it at `estimatedItemSize`, deliberately a
109
+ // lower bound — so the scroll that fires with the message computes its target
110
+ // against content that is too short and can move nothing at all. The real
111
+ // height lands a few hundred ms later (measured: 297ms, leaving the last
112
+ // message 55px behind the composer). Long enough to cover that, short enough
113
+ // that it cannot interfere with a scroll the user starts afterwards.
114
+ const NEW_MESSAGE_ANCHOR_MS = 1000;
115
+
106
116
  // Passed as the list's `keyboardOffset` to switch KeyboardChatScrollView's own
107
117
  // native `contentInset` off while leaving the rest of the component in place.
108
118
  // Its `getEffectiveHeight` interpolates the live keyboard height into
@@ -182,9 +192,15 @@ export const ChatListLegend = memo(
182
192
  // drop Android's repeat events before they reach React.
183
193
  const keyboardInsetRef = useRef(0);
184
194
  const [keyboardInset, setKeyboardInset] = useState(0);
195
+ // True while the keyboard-following loop below is driving the list.
196
+ const isFollowingKeyboardRef = useRef(false);
197
+ // Deadline until which content growth should re-anchor to the end, and
198
+ // the content height the last growth was measured against.
199
+ const anchorToEndUntilRef = useRef(0);
200
+ const lastContentHeightRef = useRef(0);
185
201
  // The keyboard's live height, written on the UI thread and sampled from
186
- // the JS thread by the tween below, so the content tracks the keyboard's
187
- // real position instead of a guessed easing curve.
202
+ // the JS thread by the following loop, so the content tracks where the
203
+ // keyboard actually is instead of a guessed easing curve.
188
204
  //
189
205
  // `useGenericKeyboardHandler` rather than `useKeyboardHandler` /
190
206
  // `useReanimatedKeyboardAnimation`: those call `useResizeMode()`, which
@@ -192,8 +208,6 @@ export const ChatListLegend = memo(
192
208
  // already owns that here. The worklet only writes a SharedValue; calling
193
209
  // `runOnJS` (or anything that reaches JS) from a keyboard worklet
194
210
  // reliably crashes Reanimated with a reentrant-lock assertion.
195
- // True while the keyboard-following loop below is driving the list.
196
- const isFollowingKeyboardRef = useRef(false);
197
211
  const liveKeyboardHeight = useSharedValue(0);
198
212
  useGenericKeyboardHandler(
199
213
  {
@@ -559,6 +573,26 @@ export const ChatListLegend = memo(
559
573
  const isAtBottom =
560
574
  contentOffset.y + layoutMeasurement.height >=
561
575
  contentSize.height - 100;
576
+ // A row that finishes measuring after the message was inserted grows
577
+ // the content under a scroll that has already run, leaving the newest
578
+ // message short of the end — behind the composer, since that is
579
+ // exactly the room the keyboard padding reserves. Re-aim at the new
580
+ // end each time that happens, for as long as the window is open.
581
+ const grew = contentSize.height > lastContentHeightRef.current;
582
+ lastContentHeightRef.current = contentSize.height;
583
+ // Measured against the true end, not `isAtBottom`: that carries a
584
+ // 100px tolerance for the scroll-to-bottom button, and the shortfall
585
+ // here is smaller than it (55px measured) while still being enough to
586
+ // leave the newest message behind the composer.
587
+ const distanceFromEnd =
588
+ contentSize.height - contentOffset.y - layoutMeasurement.height;
589
+ if (
590
+ grew &&
591
+ distanceFromEnd > 1 &&
592
+ Date.now() < anchorToEndUntilRef.current
593
+ ) {
594
+ scrollMessageToEnd({ animated: true, closeKeyboard: false });
595
+ }
562
596
 
563
597
  // Debounce animation updates
564
598
  if (scrollDebounceRef.current) {
@@ -578,7 +612,7 @@ export const ChatListLegend = memo(
578
612
  }
579
613
  }, 50);
580
614
  },
581
- [buttonOpacity, conversationId]
615
+ [buttonOpacity, conversationId, scrollMessageToEnd]
582
616
  );
583
617
 
584
618
  const handleScrollToBottom = useCallback(() => {
@@ -814,6 +848,7 @@ export const ChatListLegend = memo(
814
848
 
815
849
  if (!shouldFire) return;
816
850
 
851
+ anchorToEndUntilRef.current = Date.now() + NEW_MESSAGE_ANCHOR_MS;
817
852
  scrollMessageToEnd({ animated: true, closeKeyboard: false });
818
853
  }, [lastMessageId, scrollMessageToEnd]);
819
854