@droppii-org/chat-mobile 0.2.38 → 0.2.40

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 (53) hide show
  1. package/lib/module/components/ThreadCard/ThreadCard.js +2 -1
  2. package/lib/module/components/ThreadCard/ThreadCard.js.map +1 -1
  3. package/lib/module/components/messages/quotedMessage/index.js +7 -3
  4. package/lib/module/components/messages/quotedMessage/index.js.map +1 -1
  5. package/lib/module/core/useChatListener.js +15 -5
  6. package/lib/module/core/useChatListener.js.map +1 -1
  7. package/lib/module/screens/chat-detail/ChatCurrentQuotedMessage.js +4 -2
  8. package/lib/module/screens/chat-detail/ChatCurrentQuotedMessage.js.map +1 -1
  9. package/lib/module/screens/chat-detail/PinnedMessageBar.js +8 -3
  10. package/lib/module/screens/chat-detail/PinnedMessageBar.js.map +1 -1
  11. package/lib/module/screens/chat-detail/PinnedMessagesSheet.js +80 -110
  12. package/lib/module/screens/chat-detail/PinnedMessagesSheet.js.map +1 -1
  13. package/lib/module/screens/chat-detail/PinnedMessagesSheetBackup.js +179 -0
  14. package/lib/module/screens/chat-detail/PinnedMessagesSheetBackup.js.map +1 -0
  15. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js +18 -6
  16. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js.map +1 -1
  17. package/lib/module/translation/resources/i18n.js +3 -2
  18. package/lib/module/translation/resources/i18n.js.map +1 -1
  19. package/lib/module/utils/UIUtils.js +4 -2
  20. package/lib/module/utils/UIUtils.js.map +1 -1
  21. package/lib/module/utils/messageUtils.js +29 -5
  22. package/lib/module/utils/messageUtils.js.map +1 -1
  23. package/lib/typescript/src/components/ThreadCard/ThreadCard.d.ts.map +1 -1
  24. package/lib/typescript/src/components/messages/quotedMessage/index.d.ts.map +1 -1
  25. package/lib/typescript/src/core/useChatListener.d.ts.map +1 -1
  26. package/lib/typescript/src/screens/chat-detail/ChatCurrentQuotedMessage.d.ts.map +1 -1
  27. package/lib/typescript/src/screens/chat-detail/PinnedMessageBar.d.ts +1 -1
  28. package/lib/typescript/src/screens/chat-detail/PinnedMessageBar.d.ts.map +1 -1
  29. package/lib/typescript/src/screens/chat-detail/PinnedMessagesSheet.d.ts +1 -1
  30. package/lib/typescript/src/screens/chat-detail/PinnedMessagesSheet.d.ts.map +1 -1
  31. package/lib/typescript/src/screens/chat-detail/PinnedMessagesSheetBackup.d.ts +9 -0
  32. package/lib/typescript/src/screens/chat-detail/PinnedMessagesSheetBackup.d.ts.map +1 -0
  33. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts +2 -1
  34. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts.map +1 -1
  35. package/lib/typescript/src/translation/resources/i18n.d.ts.map +1 -1
  36. package/lib/typescript/src/types/chat.d.ts +1 -0
  37. package/lib/typescript/src/types/chat.d.ts.map +1 -1
  38. package/lib/typescript/src/utils/UIUtils.d.ts.map +1 -1
  39. package/lib/typescript/src/utils/messageUtils.d.ts +7 -0
  40. package/lib/typescript/src/utils/messageUtils.d.ts.map +1 -1
  41. package/package.json +1 -1
  42. package/src/components/ThreadCard/ThreadCard.tsx +5 -1
  43. package/src/components/messages/quotedMessage/index.tsx +7 -3
  44. package/src/core/useChatListener.ts +29 -6
  45. package/src/screens/chat-detail/ChatCurrentQuotedMessage.tsx +5 -2
  46. package/src/screens/chat-detail/PinnedMessageBar.tsx +19 -5
  47. package/src/screens/chat-detail/PinnedMessagesSheet.tsx +118 -153
  48. package/src/screens/chat-detail/PinnedMessagesSheetBackup.tsx +253 -0
  49. package/src/screens/chat-detail/legend/LegendChatMessage.tsx +26 -13
  50. package/src/translation/resources/i18n.ts +4 -2
  51. package/src/types/chat.ts +1 -1
  52. package/src/utils/UIUtils.ts +3 -1
  53. package/src/utils/messageUtils.ts +39 -6
@@ -1 +1 @@
1
- {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../../src/types/chat.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../../src/types/chat.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"UIUtils.d.ts","sourceRoot":"","sources":["../../../../src/utils/UIUtils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAgBnD,eAAO,MAAM,eAAe,GAAI,SAAS,aAAa,KAAG,IAExD,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,QAAQ,CAAC,aAAa,CAc3C,CAAC"}
1
+ {"version":3,"file":"UIUtils.d.ts","sourceRoot":"","sources":["../../../../src/utils/UIUtils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAgBnD,eAAO,MAAM,eAAe,GAAI,SAAS,aAAa,KAAG,IAExD,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,QAAQ,CAAC,aAAa,CAgB3C,CAAC"}
@@ -3,9 +3,15 @@
3
3
  */
4
4
  import { type ConversationItem, type MessageItem } from '@droppii/openim-rn-client-sdk';
5
5
  import type { IUrlMetadata } from '../types/common';
6
+ import type { TextProps } from 'react-native';
6
7
  export declare const isMessageRevoked: (message: MessageItem) => boolean;
7
8
  export declare const extractTextContent: (message: MessageItem) => string;
8
9
  export declare const getMessagePreview: (message?: MessageItem) => string;
10
+ export declare const getMessagePreviewTextProps: (message?: MessageItem) => TextProps;
11
+ export declare const getMessagePreviewParts: (message?: MessageItem) => {
12
+ text: string;
13
+ textProps: TextProps;
14
+ };
9
15
  export type PinnedMessageMediaType = 'image' | 'video' | 'file' | 'text';
10
16
  export interface PinnedMessagePreview {
11
17
  mediaType: PinnedMessageMediaType;
@@ -17,4 +23,5 @@ export declare const getPinnedMessagePreview: (message: MessageItem) => PinnedMe
17
23
  export declare const getLastMessageText: (message: MessageItem | undefined, currentUserId?: string, conversation?: ConversationItem) => string;
18
24
  export declare const getReplySenderName: (message?: MessageItem, currentUserId?: string, conversation?: ConversationItem, isSent?: boolean) => string;
19
25
  export declare const parseUrlMetadata: (ex?: string) => IUrlMetadata | undefined;
26
+ export declare const truncateMiddle: (name: string, maxLength: number) => string;
20
27
  //# sourceMappingURL=messageUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"messageUtils.d.ts","sourceRoot":"","sources":["../../../../src/utils/messageUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EACjB,MAAM,+BAA+B,CAAC;AAIvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD,eAAO,MAAM,gBAAgB,GAAI,SAAS,WAAW,KAAG,OACL,CAAC;AAEpD,eAAO,MAAM,kBAAkB,GAAI,SAAS,WAAW,KAAG,MAQzD,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,UAAU,WAAW,KAAG,MAqEzD,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzE,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,sBAAsB,CAAC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAmBD,eAAO,MAAM,uBAAuB,GAClC,SAAS,WAAW,KACnB,oBA0DF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,SAAS,WAAW,GAAG,SAAS,EAChC,gBAAgB,MAAM,EACtB,eAAe,gBAAgB,KAC9B,MAkBF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,UAAU,WAAW,EACrB,gBAAgB,MAAM,EACtB,eAAe,gBAAgB,EAC/B,SAAS,OAAO,KACf,MAOF,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,KAAG,YAAY,GAAG,SAS7D,CAAC"}
1
+ {"version":3,"file":"messageUtils.d.ts","sourceRoot":"","sources":["../../../../src/utils/messageUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EACjB,MAAM,+BAA+B,CAAC;AAIvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,eAAO,MAAM,gBAAgB,GAAI,SAAS,WAAW,KAAG,OACL,CAAC;AAEpD,eAAO,MAAM,kBAAkB,GAAI,SAAS,WAAW,KAAG,MAQzD,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,UAAU,WAAW,KAAG,MAoEzD,CAAC;AAEF,eAAO,MAAM,0BAA0B,GACrC,UAAU,WAAW,KACpB,SAUF,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,UAAU,WAAW,KACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,SAAS,CAAA;CAGrC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzE,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,sBAAsB,CAAC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAmBD,eAAO,MAAM,uBAAuB,GAClC,SAAS,WAAW,KACnB,oBA0DF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,SAAS,WAAW,GAAG,SAAS,EAChC,gBAAgB,MAAM,EACtB,eAAe,gBAAgB,KAC9B,MAkBF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,UAAU,WAAW,EACrB,gBAAgB,MAAM,EACtB,eAAe,gBAAgB,EAC/B,SAAS,OAAO,KACf,MAOF,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,KAAG,YAAY,GAAG,SAS7D,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,EAAE,WAAW,MAAM,KAAG,MAUhE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@droppii-org/chat-mobile",
3
- "version": "0.2.38",
3
+ "version": "0.2.40",
4
4
  "description": "Droppii chat mobile",
5
5
  "keywords": [
6
6
  "react-native",
@@ -7,7 +7,10 @@ import { AvatarSection } from './AvatarSection';
7
7
  import { NamePrefixIcon } from './NamePrefixIcon';
8
8
  import { UnreadBadge } from './UnreadBadge';
9
9
  import { formatTimestamp } from '../../utils/dateTimeUtils';
10
- import { getLastMessageText } from '../../utils/messageUtils';
10
+ import {
11
+ getLastMessageText,
12
+ getMessagePreviewTextProps,
13
+ } from '../../utils/messageUtils';
11
14
  import { useConversation, useUserStore } from '../../store';
12
15
  import {
13
16
  MessageReceiveOptType,
@@ -154,6 +157,7 @@ const ThreadCard = memo(({ item, onPress }: ThreadCardProps) => {
154
157
  color={hasUnread ? KColors.black : KColors.gray.normal}
155
158
  numberOfLines={1}
156
159
  flex
160
+ {...getMessagePreviewTextProps(latestMsgData)}
157
161
  >
158
162
  {lastMessageText}
159
163
  </KLabel.Text>
@@ -13,7 +13,7 @@ import { StyleSheet } from 'react-native';
13
13
  import { CHAT_BUBBLE_COLORS } from '../../../screens/chat-detail/constants';
14
14
  import { MessageType } from '@droppii/openim-rn-client-sdk';
15
15
  import {
16
- getMessagePreview,
16
+ getMessagePreviewParts,
17
17
  getReplySenderName,
18
18
  parseUrlMetadata,
19
19
  } from '../../../utils/messageUtils';
@@ -35,6 +35,8 @@ const QuotedMessage = memo((props: QuotedMessageProps) => {
35
35
 
36
36
  const quotedMessage = message?.quoteElem?.quoteMessage;
37
37
 
38
+ const messagePreview = getMessagePreviewParts(quotedMessage);
39
+
38
40
  const timeLabel = formatMessageTime(createdAtTime);
39
41
 
40
42
  const imageUrl = useMemo(() => {
@@ -102,7 +104,7 @@ const QuotedMessage = memo((props: QuotedMessageProps) => {
102
104
  resizeMode="contain"
103
105
  />
104
106
  </KContainer.VisibleView>
105
- <KContainer.View style={styles.content}>
107
+ <KContainer.View flexS={1} style={styles.content}>
106
108
  <KLabel.Text typo="TextNmMedium" numberOfLines={1}>
107
109
  {getReplySenderName(
108
110
  quotedMessage,
@@ -115,8 +117,9 @@ const QuotedMessage = memo((props: QuotedMessageProps) => {
115
117
  typo="TextSmNormal"
116
118
  color={KColors.gray.light}
117
119
  numberOfLines={1}
120
+ {...messagePreview.textProps}
118
121
  >
119
- {getMessagePreview(quotedMessage)}
122
+ {messagePreview.text}
120
123
  </KLabel.Text>
121
124
  </KContainer.View>
122
125
  </KContainer.Touchable>
@@ -156,6 +159,7 @@ const styles = StyleSheet.create({
156
159
  borderTopRightRadius: KRadiusValue['3x'],
157
160
  borderBottomRightRadius: KRadiusValue['3x'],
158
161
  paddingRight: KSpacingValue['0.5rem'],
162
+ maxWidth: '100%',
159
163
  },
160
164
  dot: {
161
165
  width: 3,
@@ -1,5 +1,6 @@
1
1
  import OpenIMSDK, {
2
2
  MessageReceiveOptType,
3
+ MessageType,
3
4
  OpenIMEvent,
4
5
  type ConversationItem,
5
6
  type GroupMemberItem,
@@ -11,12 +12,14 @@ import { useCallback, useEffect } from 'react';
11
12
  import { useConversationStore } from '../store/conversation';
12
13
  import { ToastFlashMessage } from '../utils/toastFlashMessage';
13
14
  import { useUserStore } from '../store/user';
14
- import { getLastMessageText } from '../utils/messageUtils';
15
+ import { getLastMessageText, truncateMiddle } from '../utils/messageUtils';
15
16
  import { useChatContext } from '../context';
16
17
  import isEmpty from 'lodash/isEmpty';
17
18
  import { markMessageRevoked, useMessageStore } from '../store/message';
18
19
  import { syncPinnedMessagesOnEvent } from '../hooks/message/usePinMessage';
19
20
 
21
+ const MAX_TOAST_FILE_NAME_LENGTH = 40;
22
+
20
23
  export const useChatListener = () => {
21
24
  const updateOneMessage = useMessageStore((state) => state.updateOneMessage);
22
25
  const currentUserId = useUserStore((s) => s.user?.userID);
@@ -37,18 +40,37 @@ export const useChatListener = () => {
37
40
 
38
41
  const onConversationChanged = useCallback(
39
42
  (conversations: ConversationItem[]) => {
40
- useConversationStore.getState().updateConversations(conversations);
43
+ const oldMap = useConversationStore.getState().map;
41
44
  if (isShowFLashMessage) {
42
45
  for (const conversation of conversations) {
46
+ const oldConversation = oldMap[conversation.conversationID];
43
47
  if (
44
- conversation.recvMsgOpt === MessageReceiveOptType.NotNotify &&
45
- !isEmpty(conversation?.latestMsg)
48
+ conversation.recvMsgOpt === MessageReceiveOptType.NotNotify ||
49
+ isEmpty(conversation?.latestMsg) ||
50
+ oldConversation?.latestMsgSendTime ===
51
+ conversation?.latestMsgSendTime
46
52
  ) {
47
53
  continue;
48
54
  }
49
- const latestMsg = JSON.parse(conversation.latestMsg || '{}');
55
+ const latestMsg: MessageItem = JSON.parse(
56
+ conversation.latestMsg || '{}'
57
+ );
58
+ const messageForToast =
59
+ latestMsg.contentType === MessageType.FileMessage &&
60
+ latestMsg.fileElem?.fileName
61
+ ? {
62
+ ...latestMsg,
63
+ fileElem: {
64
+ ...latestMsg.fileElem,
65
+ fileName: truncateMiddle(
66
+ latestMsg.fileElem.fileName,
67
+ MAX_TOAST_FILE_NAME_LENGTH
68
+ ),
69
+ },
70
+ }
71
+ : latestMsg;
50
72
  const lastMessageText = getLastMessageText(
51
- latestMsg,
73
+ messageForToast,
52
74
  currentUserId,
53
75
  conversation
54
76
  );
@@ -62,6 +84,7 @@ export const useChatListener = () => {
62
84
  },
63
85
  });
64
86
  }
87
+ useConversationStore.getState().updateConversations(conversations);
65
88
  }
66
89
  },
67
90
  [currentUserId, isShowFLashMessage, onPressFlashMessage]
@@ -10,7 +10,7 @@ import { memo, useMemo } from 'react';
10
10
  import { StyleSheet } from 'react-native';
11
11
  import { useChatDetailContext } from '../../context';
12
12
  import {
13
- getMessagePreview,
13
+ getMessagePreviewParts,
14
14
  getReplySenderName,
15
15
  parseUrlMetadata,
16
16
  } from '../../utils/messageUtils';
@@ -23,6 +23,8 @@ export const ChatCurrentQuotedMessage = memo(() => {
23
23
  const { quotedMessage, conversation, setQuotedMessage } =
24
24
  useChatDetailContext();
25
25
 
26
+ const messagePreview = getMessagePreviewParts(quotedMessage);
27
+
26
28
  const currentUserId = useUserStore((s) => s.user?.userID);
27
29
 
28
30
  const imageUrl = useMemo(() => {
@@ -89,8 +91,9 @@ export const ChatCurrentQuotedMessage = memo(() => {
89
91
  typo="TextSmNormal"
90
92
  color={KColors.gray.light}
91
93
  numberOfLines={1}
94
+ {...messagePreview.textProps}
92
95
  >
93
- {getMessagePreview(quotedMessage)}
96
+ {messagePreview.text}
94
97
  </KLabel.Text>
95
98
  </KContainer.View>
96
99
  <KContainer.Touchable onPress={() => setQuotedMessage(undefined)}>
@@ -10,10 +10,16 @@ import {
10
10
  } from '@droppii/libs';
11
11
  import { trans } from '../../translation';
12
12
  import {
13
- getMessagePreview,
13
+ getMessagePreviewParts,
14
14
  getPinnedMessagePreview,
15
15
  } from '../../utils/messageUtils';
16
- import type { MessageItem } from '@droppii/openim-rn-client-sdk';
16
+ import { MessageType, type MessageItem } from '@droppii/openim-rn-client-sdk';
17
+
18
+ const HIDDEN_PREVIEW_TEXT_TYPES = new Set([
19
+ MessageType.PictureMessage,
20
+ MessageType.VideoMessage,
21
+ MessageType.MergeMessage,
22
+ ]);
17
23
 
18
24
  interface PinnedMessageBarProps {
19
25
  messages: MessageItem[];
@@ -84,6 +90,8 @@ export const PinnedMessageBar = memo(
84
90
  latest.sendID === currentUserId ? 'Bạn' : latest.senderNickname || '';
85
91
  const remainingCount = messages.length - 1;
86
92
  const { subtitleKey } = getPinnedMessagePreview(latest);
93
+ const messagePreview = getMessagePreviewParts(latest);
94
+ const hidePreviewText = HIDDEN_PREVIEW_TEXT_TYPES.has(latest.contentType);
87
95
 
88
96
  return (
89
97
  <KContainer.Touchable
@@ -95,9 +103,15 @@ export const PinnedMessageBar = memo(
95
103
 
96
104
  <KContainer.View row alignItems flex paddingR="0.75rem">
97
105
  <KContainer.View style={styles.content}>
98
- <KLabel.Text typo="TextNmMedium" numberOfLines={1}>
99
- {getMessagePreview(latest)}
100
- </KLabel.Text>
106
+ {!hidePreviewText && (
107
+ <KLabel.Text
108
+ typo="TextNmMedium"
109
+ numberOfLines={1}
110
+ {...messagePreview.textProps}
111
+ >
112
+ {messagePreview.text}
113
+ </KLabel.Text>
114
+ )}
101
115
 
102
116
  <KContainer.View row alignItems paddingR="0.75rem">
103
117
  <KImage.VectorIcons
@@ -1,127 +1,29 @@
1
- import {
2
- forwardRef,
3
- memo,
4
- useCallback,
5
- useImperativeHandle,
6
- useRef,
7
- useState,
8
- } from 'react';
1
+ import { memo, useCallback } from 'react';
9
2
  import type { ReactNode } from 'react';
10
- import { Modal, Pressable, StyleSheet, type View } from 'react-native';
11
- import type { MessageItem } from '@droppii/openim-rn-client-sdk';
12
- import { KContainer, KLabel, KColors } from '@droppii/libs';
3
+ import { StyleSheet } from 'react-native';
4
+ import { MessageType, type MessageItem } from '@droppii/openim-rn-client-sdk';
5
+ import {
6
+ KContainer,
7
+ KLabel,
8
+ KColors,
9
+ KImage,
10
+ KSpacingValue,
11
+ } from '@droppii/libs';
13
12
  import { UIUtils } from '../../utils/UIUtils';
14
13
  import { trans } from '../../translation';
15
14
  import { usePinnedMessageStore } from '../../store/pinnedMessage';
16
15
  import { LegendChatMessage } from './legend/LegendChatMessage';
17
- import { formatMessageTime, messageStyles } from './legend/messageTypes';
18
- import { MessageToolboxWrapper } from './messageToolbox/MessageToolboxWrapper';
19
- import { MessageToolboxMenu } from './messageToolbox/MessageToolboxMenu';
20
- import type { MeasuredRect } from './messageToolbox/types';
21
-
22
- interface PinnedMessageToolboxRef {
23
- show: (message: MessageItem, rect: MeasuredRect) => void;
24
- hide: () => void;
25
- }
26
-
27
- interface PinnedMessageToolboxOverlayProps {
28
- currentUserId?: string;
29
- unpinMessage: (message: MessageItem) => void | Promise<void>;
30
- customMessageItemFactory?: (item: MessageItem) => ReactNode;
31
- }
32
-
33
- // Mirrors MessageToolboxOverlay (used for the main chat list's long-press
34
- // menu) but restricted to the 2 actions relevant to an already-pinned
35
- // message: unpin and jump to the original message.
36
- const PinnedMessageToolboxOverlay = memo(
37
- forwardRef<PinnedMessageToolboxRef, PinnedMessageToolboxOverlayProps>(
38
- ({ currentUserId, unpinMessage, customMessageItemFactory }, ref) => {
39
- const [visible, setVisible] = useState(false);
40
- const [message, setMessage] = useState<MessageItem | undefined>(
41
- undefined
42
- );
43
- const [rect, setRect] = useState<MeasuredRect | null>(null);
44
-
45
- const hide = useCallback(() => {
46
- setVisible(false);
47
- setMessage(undefined);
48
- setRect(null);
49
- }, []);
50
-
51
- const show = useCallback((msg: MessageItem, msgRect: MeasuredRect) => {
52
- setMessage(msg);
53
- setRect(msgRect);
54
- setVisible(true);
55
- }, []);
56
-
57
- useImperativeHandle(ref, () => ({ show, hide }), [show, hide]);
58
-
59
- const handleUnpinMessage = useCallback(() => {
60
- if (!message) return;
61
- hide();
62
- unpinMessage(message);
63
- }, [message, hide, unpinMessage]);
64
-
65
- const handleViewOriginalMessage = useCallback(() => {
66
- if (!message) return;
67
- hide();
68
- // TODO: implement navigating to / highlighting the original message
69
- }, [message, hide]);
70
-
71
- if (!visible || !message || !rect) {
72
- return null;
73
- }
74
-
75
- const isOutgoing = message.sendID === currentUserId;
76
-
77
- return (
78
- <Modal
79
- visible={visible}
80
- transparent
81
- statusBarTranslucent
82
- animationType="fade"
83
- onRequestClose={hide}
84
- >
85
- <Pressable style={styles.backdrop} onPress={hide} />
86
-
87
- <MessageToolboxWrapper
88
- rect={rect}
89
- isOutgoing={isOutgoing}
90
- message={
91
- <LegendChatMessage
92
- message={message}
93
- isOutgoing={isOutgoing}
94
- createdAtTime={message.sendTime || message.createTime}
95
- customMessageItemFactory={customMessageItemFactory}
96
- />
97
- }
98
- toolbox={
99
- <MessageToolboxMenu
100
- showUnpinMessage
101
- showViewOriginalMessage
102
- onUnpinMessage={handleUnpinMessage}
103
- onViewOriginalMessage={handleViewOriginalMessage}
104
- />
105
- }
106
- />
107
- </Modal>
108
- );
109
- }
110
- )
111
- );
112
-
113
- PinnedMessageToolboxOverlay.displayName = 'PinnedMessageToolboxOverlay';
114
-
115
- const styles = StyleSheet.create({
116
- backdrop: {
117
- position: 'absolute',
118
- top: 0,
119
- left: 0,
120
- right: 0,
121
- bottom: 0,
122
- backgroundColor: 'rgba(0,0,0,0.75)',
123
- },
124
- });
16
+ import { formatMessageTime } from './legend/messageTypes';
17
+
18
+ // Text/quote/link bubbles already render their own timestamp for incoming
19
+ // messages (see textMessage, quotedMessage, linkMessage) — skip the external
20
+ // label for those to avoid showing the time twice.
21
+ const SELF_RENDERS_TIME_FOR_INCOMING = new Set([
22
+ MessageType.TextMessage,
23
+ MessageType.AtTextMessage,
24
+ MessageType.QuoteMessage,
25
+ MessageType.UrlTextMessage,
26
+ ]);
125
27
 
126
28
  interface PinnedMessagesSheetContentProps {
127
29
  currentUserId?: string;
@@ -136,19 +38,25 @@ const PinnedMessagesSheetContent = memo(
136
38
  customMessageItemFactory,
137
39
  }: PinnedMessagesSheetContentProps) => {
138
40
  const messages = usePinnedMessageStore((state) => state.messages);
139
- const toolboxRef = useRef<PinnedMessageToolboxRef>(null);
140
- const rowRefsMap = useRef<Map<string, View | null>>(new Map());
141
-
142
- const handleLongPress = useCallback(
143
- (messageId: string, message: MessageItem) => {
144
- const node = rowRefsMap.current.get(messageId);
145
- node?.measureInWindow((x, y, width, height) => {
146
- toolboxRef.current?.show(message, { x, y, width, height });
147
- });
41
+
42
+ const handleUnpinMessage = useCallback(
43
+ async (message: MessageItem) => {
44
+ await unpinMessage(message);
45
+ if (usePinnedMessageStore.getState().messages.length === 0) {
46
+ UIUtils.bottomSheet.dismiss();
47
+ }
148
48
  },
149
- []
49
+ [unpinMessage]
150
50
  );
151
51
 
52
+ const handlePressMessage = useCallback(() => {
53
+ UIUtils.bottomSheet.dismiss();
54
+ UIUtils.alert.open({
55
+ title: trans('chat:view_original_message'),
56
+ message: trans('chat:scroll_to_message_todo'),
57
+ });
58
+ }, []);
59
+
152
60
  return (
153
61
  <KContainer.View paddingV="0.5rem">
154
62
  <KLabel.Text
@@ -164,28 +72,58 @@ const PinnedMessagesSheetContent = memo(
164
72
  const isOutgoing = message.sendID === currentUserId;
165
73
  const messageId = message.clientMsgID || message.serverMsgID;
166
74
  const createdAtTime = message.sendTime || message.createTime;
167
- const timeLabel = formatMessageTime(createdAtTime);
75
+ const hasInternalTimeLabel =
76
+ !isOutgoing &&
77
+ SELF_RENDERS_TIME_FOR_INCOMING.has(message.contentType);
78
+ const timeLabel = hasInternalTimeLabel
79
+ ? ''
80
+ : formatMessageTime(createdAtTime);
81
+
82
+ const unpinButton = (
83
+ <KContainer.Touchable
84
+ center
85
+ br="round"
86
+ width={28}
87
+ height={28}
88
+ background={KColors.background}
89
+ style={
90
+ isOutgoing ? styles.unpinButtonLeft : styles.unpinButtonRight
91
+ }
92
+ onPress={() => handleUnpinMessage(message)}
93
+ >
94
+ <KImage.VectorIcons
95
+ name="thumbtack-off-o"
96
+ provider="DroppiiNew"
97
+ size={14}
98
+ color={KColors.gray.dark}
99
+ />
100
+ </KContainer.Touchable>
101
+ );
168
102
 
169
103
  return (
170
104
  <KContainer.View
171
105
  key={messageId}
172
- ref={(node: View | null) => {
173
- if (node) rowRefsMap.current.set(messageId, node);
174
- else rowRefsMap.current.delete(messageId);
175
- }}
176
- style={
177
- isOutgoing
178
- ? messageStyles.messageRowRight
179
- : messageStyles.messageRowLeft
180
- }
106
+ style={isOutgoing ? styles.rowRight : styles.rowLeft}
181
107
  >
182
- <LegendChatMessage
183
- message={message}
184
- isOutgoing={isOutgoing}
185
- createdAtTime={createdAtTime}
186
- onLongPress={() => handleLongPress(messageId, message)}
187
- customMessageItemFactory={customMessageItemFactory}
188
- />
108
+ <KContainer.View
109
+ style={[
110
+ styles.messageRow,
111
+ isOutgoing ? styles.messageRowRight : styles.messageRowLeft,
112
+ ]}
113
+ >
114
+ {isOutgoing && unpinButton}
115
+
116
+ <LegendChatMessage
117
+ message={message}
118
+ isOutgoing={isOutgoing}
119
+ createdAtTime={createdAtTime}
120
+ onPress={handlePressMessage}
121
+ customMessageItemFactory={customMessageItemFactory}
122
+ />
123
+
124
+ {!isOutgoing && unpinButton}
125
+ </KContainer.View>
126
+
189
127
  {!!timeLabel && (
190
128
  <KLabel.Text
191
129
  typo="TextXsNormal"
@@ -198,13 +136,6 @@ const PinnedMessagesSheetContent = memo(
198
136
  </KContainer.View>
199
137
  );
200
138
  })}
201
-
202
- <PinnedMessageToolboxOverlay
203
- ref={toolboxRef}
204
- currentUserId={currentUserId}
205
- unpinMessage={unpinMessage}
206
- customMessageItemFactory={customMessageItemFactory}
207
- />
208
139
  </KContainer.View>
209
140
  );
210
141
  }
@@ -212,6 +143,40 @@ const PinnedMessagesSheetContent = memo(
212
143
 
213
144
  PinnedMessagesSheetContent.displayName = 'PinnedMessagesSheetContent';
214
145
 
146
+ const UNPIN_BUTTON_GAP = KSpacingValue['0.5rem'];
147
+
148
+ const styles = StyleSheet.create({
149
+ rowLeft: {
150
+ width: '100%',
151
+ paddingHorizontal: KSpacingValue['0.75rem'],
152
+ marginBottom: KSpacingValue['0.25rem'],
153
+ alignItems: 'flex-start',
154
+ },
155
+ rowRight: {
156
+ width: '100%',
157
+ paddingHorizontal: KSpacingValue['0.75rem'],
158
+ marginBottom: KSpacingValue['0.25rem'],
159
+ alignItems: 'flex-end',
160
+ },
161
+ messageRow: {
162
+ width: '100%',
163
+ flexDirection: 'row',
164
+ alignItems: 'center',
165
+ },
166
+ messageRowLeft: {
167
+ justifyContent: 'flex-start',
168
+ },
169
+ messageRowRight: {
170
+ justifyContent: 'flex-end',
171
+ },
172
+ unpinButtonLeft: {
173
+ marginRight: UNPIN_BUTTON_GAP,
174
+ },
175
+ unpinButtonRight: {
176
+ marginLeft: UNPIN_BUTTON_GAP,
177
+ },
178
+ });
179
+
215
180
  export interface OpenPinnedMessagesSheetParams {
216
181
  currentUserId?: string;
217
182
  unpinMessage: (message: MessageItem) => void | Promise<void>;