@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
@@ -0,0 +1,31 @@
1
+ import { KColors, KContainer, KNavigation } from '@droppii/libs';
2
+ import { ActivityIndicator } from 'react-native';
3
+ import { useNavigation } from '@react-navigation/native';
4
+
5
+ export const ChatDetailLoading = () => {
6
+ const navigation = useNavigation();
7
+ return (
8
+ <KContainer.Page flex edges={['bottom']}>
9
+ <KNavigation.Header
10
+ theme="light"
11
+ alignment="left"
12
+ size="small"
13
+ disableCenterSpace
14
+ shadow
15
+ leftButton={{
16
+ id: 'back',
17
+ icon: {
18
+ size: 24,
19
+ vectorName: 'arrow-left-o',
20
+ vectorProvider: 'DroppiiNew',
21
+ tintColor: KColors.primary.normal,
22
+ },
23
+ onPress: navigation.goBack,
24
+ }}
25
+ />
26
+ <KContainer.View flex center>
27
+ <ActivityIndicator size="small" color={KColors.primary.normal} />
28
+ </KContainer.View>
29
+ </KContainer.Page>
30
+ );
31
+ };
@@ -193,7 +193,7 @@ export const useMessageStore = create<MessageStore>()((set, get) => ({
193
193
  initLoading: false,
194
194
  });
195
195
 
196
- const targetMessage = currentMessages.find(
196
+ const targetMessage = newMessages.find(
197
197
  (msg) => msg.clientMsgID === startClientMsgId
198
198
  );
199
199
 
@@ -65,3 +65,34 @@ export const isGroupConversation = (
65
65
  ) => {
66
66
  return conversation?.peerType === PeerType.Group;
67
67
  };
68
+
69
+ const GROUP_CONVERSATION_ID_PREFIX = 'sg_';
70
+
71
+ /**
72
+ * Group conversationIds are formatted as "sg_<groupID>" — derive the groupID
73
+ * straight from the id when a full ConversationItem isn't available yet (e.g.
74
+ * a non-member previewing a public group via deeplink has no synced
75
+ * conversation object to read groupID off of).
76
+ */
77
+ export const getGroupIdFromConversationId = (conversationId?: string) =>
78
+ conversationId?.startsWith(GROUP_CONVERSATION_ID_PREFIX)
79
+ ? conversationId.slice(GROUP_CONVERSATION_ID_PREFIX.length)
80
+ : '';
81
+
82
+ const SINGLE_CONVERSATION_ID_PREFIX = 'si_';
83
+
84
+ export const isSingleConversationId = (conversationId: string): boolean =>
85
+ conversationId.startsWith(SINGLE_CONVERSATION_ID_PREFIX);
86
+
87
+ /**
88
+ * A 1v1 conversationId is "si_<userA>_<userB>" (see `getConversationID`), with
89
+ * no fixed order between the two — same as the forward/reverse match
90
+ * `isSameConversation` does above. Used to tell whether the logged-in user is
91
+ * actually a participant when no local conversation record has synced (e.g. a
92
+ * deeplink into a 1v1 the current account has no access to). Only meaningful
93
+ * once `isSingleConversationId` is true.
94
+ */
95
+ export const isConversationParticipant = (
96
+ conversationId: string,
97
+ userId?: string
98
+ ): boolean => !!userId && conversationId.split('_').includes(userId);
@@ -4,7 +4,10 @@ import {
4
4
  type ConversationItem,
5
5
  type MessageItem,
6
6
  } from '@droppii/openim-rn-client-sdk';
7
- import { getConversationID } from './conversation';
7
+ import {
8
+ getConversationID,
9
+ getGroupIdFromConversationId,
10
+ } from './conversation';
8
11
 
9
12
  /**
10
13
  * Canonical timestamp for a message. `sendTime` is 0 until the SDK stamps an
@@ -153,9 +156,9 @@ export const getReceiverId = (conversation?: ConversationItem) => {
153
156
  if (conversation == null) return { groupID: '', recvID: '' };
154
157
 
155
158
  if (conversation.peerType === PeerType.Group) {
156
- // Group conversation: groupID is embedded after the "sg_" prefix
157
159
  const groupID =
158
- conversation.groupID || conversation.conversationID.slice(3);
160
+ conversation.groupID ||
161
+ getGroupIdFromConversationId(conversation.conversationID);
159
162
  return { groupID: groupID ?? '', recvID: '' };
160
163
  }
161
164