@medipha/chat 1.0.14
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.
- package/README.md +103 -0
- package/dist/api/client.d.ts +5 -0
- package/dist/features/composer/attachment-file-helpers.d.ts +22 -0
- package/dist/features/composer/attachments/attachment-buttons.d.ts +8 -0
- package/dist/features/composer/conversation-composer.d.ts +20 -0
- package/dist/features/composer/editor/font-size-extension.d.ts +18 -0
- package/dist/features/composer/editor/mention-suggestion-list.d.ts +15 -0
- package/dist/features/composer/editor/paste-text-style.d.ts +5 -0
- package/dist/features/composer/emoji/emoji-picker-button.d.ts +9 -0
- package/dist/features/composer/emoji/emoji-shortcode-extension.d.ts +9 -0
- package/dist/features/composer/emoji/emoji-shortcodes.d.ts +2 -0
- package/dist/features/composer/format-bar/format-bar.d.ts +14 -0
- package/dist/features/composer/more-menu/more-menu.d.ts +4 -0
- package/dist/features/composer/pending-attachment.d.ts +10 -0
- package/dist/features/composer/reply/composer-reply-banner.d.ts +11 -0
- package/dist/features/composer/reply/use-reply-target.d.ts +12 -0
- package/dist/features/composer/stickers.d.ts +6 -0
- package/dist/features/composer/toolbar/composer-toolbar.d.ts +19 -0
- package/dist/features/composer/typing/use-typing-notifier.d.ts +11 -0
- package/dist/features/composer/use-attachment-upload.d.ts +4 -0
- package/dist/features/composer/use-pending-attachments.d.ts +16 -0
- package/dist/features/create-conversation/create-conversation-panel.d.ts +9 -0
- package/dist/features/create-conversation/tabs/create-group-tab.d.ts +13 -0
- package/dist/features/create-conversation/tabs/direct-chat-tab.d.ts +12 -0
- package/dist/features/create-conversation/tabs/selected-members-modal.d.ts +11 -0
- package/dist/features/files/file-attachment.d.ts +24 -0
- package/dist/features/forward/forward-dialog.d.ts +11 -0
- package/dist/features/forward/use-forward-message.d.ts +21 -0
- package/dist/features/media-preview/media-preview-modal.d.ts +23 -0
- package/dist/features/media-preview/use-image-lightbox.d.ts +16 -0
- package/dist/features/message-list/bubble/message-actions/message-actions-menu.d.ts +27 -0
- package/dist/features/message-list/bubble/message-bubble.d.ts +53 -0
- package/dist/features/message-list/bubble/message-content-body.d.ts +12 -0
- package/dist/features/message-list/bubble/message-reactions.d.ts +18 -0
- package/dist/features/message-list/bubble/rich-message-content.d.ts +8 -0
- package/dist/features/message-list/overlays/message-details/message-details-modal.d.ts +16 -0
- package/dist/features/message-list/overlays/message-details/use-message-details-modal.d.ts +14 -0
- package/dist/features/message-list/overlays/message-menu/use-message-menu.d.ts +21 -0
- package/dist/features/message-list/overlays/reaction/reaction-modal.d.ts +22 -0
- package/dist/features/message-list/overlays/reaction/use-reaction-modal.d.ts +23 -0
- package/dist/features/message-list/overlays/reaction/use-reaction-picker.d.ts +8 -0
- package/dist/features/message-list/overlays/system-members/system-members-modal.d.ts +22 -0
- package/dist/features/message-list/overlays/system-members/use-system-members-modal.d.ts +18 -0
- package/dist/features/message-list/use-message-removal.d.ts +12 -0
- package/dist/features/message-list/use-message-timeline-scroll.d.ts +25 -0
- package/dist/features/message-window/use-message-window.d.ts +46 -0
- package/dist/features/pinned-messages/pinned-messages-bar.d.ts +18 -0
- package/dist/features/pinned-messages/use-pinned-messages.d.ts +21 -0
- package/dist/features/typing/use-typing-indicator.d.ts +12 -0
- package/dist/index.cjs +278 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +66322 -0
- package/dist/module/chat-module.d.ts +3 -0
- package/dist/module/chat-module.types.d.ts +11 -0
- package/dist/module/chat-routes.d.ts +4 -0
- package/dist/module/chat-runtime-context.d.ts +5 -0
- package/dist/pages/Setting/archive/archive-attachment-preview.d.ts +13 -0
- package/dist/pages/Setting/archive/archive-file-list.d.ts +15 -0
- package/dist/pages/Setting/archive/archive-helpers.d.ts +37 -0
- package/dist/pages/Setting/archive/archive-media-grid.d.ts +14 -0
- package/dist/pages/Setting/archive/archive-view.d.ts +19 -0
- package/dist/pages/Setting/archive/hooks/use-conversation-archive.d.ts +22 -0
- package/dist/pages/Setting/conversation-settings-panel.d.ts +20 -0
- package/dist/pages/Setting/hooks/use-conversation-settings.d.ts +41 -0
- package/dist/pages/Setting/hooks/use-search-panel.d.ts +7 -0
- package/dist/pages/Setting/index.d.ts +39 -0
- package/dist/pages/Setting/members/add-member-modal.d.ts +11 -0
- package/dist/pages/Setting/members/group-members-modal.d.ts +21 -0
- package/dist/pages/Setting/members/hooks/use-rename-group-dialog.d.ts +15 -0
- package/dist/pages/Setting/members/member-selection-footer.d.ts +12 -0
- package/dist/pages/Setting/members/members-list-modal.d.ts +29 -0
- package/dist/pages/Setting/members/settings-modal.d.ts +36 -0
- package/dist/pages/Setting/members/use-member-selection.d.ts +18 -0
- package/dist/pages/Setting/search-panel.d.ts +13 -0
- package/dist/pages/conversation/conversation-detail/conversation-detail.d.ts +92 -0
- package/dist/pages/conversation/conversation-footer/conversation-footer.d.ts +42 -0
- package/dist/pages/conversation/conversation-header/conversation-header.d.ts +27 -0
- package/dist/pages/conversation/hooks/use-current-membership.d.ts +14 -0
- package/dist/pages/conversation/index.d.ts +28 -0
- package/dist/pages/conversations/empty-state/conversation-empty-state.d.ts +3 -0
- package/dist/pages/conversations/index.d.ts +4 -0
- package/dist/pages/sidebar/hooks/use-conversations.d.ts +17 -0
- package/dist/pages/sidebar/index.d.ts +4 -0
- package/dist/pages/sidebar/sidbar-conversation-list/sidbar-conversation-list.d.ts +13 -0
- package/dist/pages/sidebar/sidebar-filter/sidebar-filter.d.ts +13 -0
- package/dist/pages/sidebar/sidebar-header-infor/sidebar-header-infor.d.ts +4 -0
- package/dist/shared/components/banner-carousel.d.ts +9 -0
- package/dist/shared/components/conversation-avatar.d.ts +19 -0
- package/dist/shared/components/date-range-filter-pill.d.ts +17 -0
- package/dist/shared/components/download-action.d.ts +11 -0
- package/dist/shared/components/filter-pill.d.ts +15 -0
- package/dist/shared/components/image-not-available.d.ts +12 -0
- package/dist/shared/components/image-with-fallback.d.ts +13 -0
- package/dist/shared/components/load-more-sentinel.d.ts +15 -0
- package/dist/shared/components/quote-icon.d.ts +5 -0
- package/dist/shared/components/search-empty-state.d.ts +8 -0
- package/dist/shared/components/shared-icon.d.ts +5 -0
- package/dist/shared/components/user-avatar.d.ts +12 -0
- package/dist/shared/components/user-profile-modal.d.ts +13 -0
- package/dist/shared/components/verified-badge.d.ts +5 -0
- package/dist/shared/helper/dayjs-date-picker.d.ts +14 -0
- package/dist/shared/hooks/use-directory-filter.d.ts +13 -0
- package/dist/shared/hooks/use-user-profile-modal.d.ts +9 -0
- package/dist/socket/chatSocket.d.ts +6 -0
- package/dist/store/authStore.d.ts +34 -0
- package/dist/store/connectionStore.d.ts +8 -0
- package/dist/store/conversationsStore.d.ts +38 -0
- package/dist/store/forwardStore.d.ts +14 -0
- package/dist/store/pinnedMessagesStore.d.ts +16 -0
- package/dist/store/presenceStore.d.ts +11 -0
- package/dist/store/verifiedPermissionsStore.d.ts +20 -0
- package/dist/styles.css +2 -0
- package/dist/utils/chat-display.d.ts +44 -0
- package/dist/utils/chat-member-resolvers.d.ts +9 -0
- package/dist/utils/chat-toast.d.ts +18 -0
- package/dist/utils/chat.d.ts +282 -0
- package/dist/utils/token.d.ts +0 -0
- package/dist/utils/work-status.d.ts +15 -0
- package/package.json +96 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ChatMessage, ChatUser, ConversationMember } from '../../../../utils/chat';
|
|
2
|
+
interface MessageDetailsModalProps {
|
|
3
|
+
message: ChatMessage;
|
|
4
|
+
isGroup: boolean;
|
|
5
|
+
members: ConversationMember[] | undefined;
|
|
6
|
+
otherMember: ConversationMember | undefined;
|
|
7
|
+
currentUserId: string | null;
|
|
8
|
+
authUser: ChatUser | null;
|
|
9
|
+
/** Members (besides the sender) who've read up to this message; `null` means the group
|
|
10
|
+
* is over MAX_DETAILED_SEEN_MEMBERS and details aren't computed at all. */
|
|
11
|
+
seenBy: ConversationMember[] | null;
|
|
12
|
+
onClose: () => void;
|
|
13
|
+
}
|
|
14
|
+
/** "Thông tin tin nhắn" dialog — sender/content/time preview plus a seen-by list. */
|
|
15
|
+
export declare function MessageDetailsModal({ message, isGroup, members, otherMember, currentUserId, authUser, seenBy, onClose, }: MessageDetailsModalProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ChatMessage, ConversationMember } from '../../../../utils/chat';
|
|
2
|
+
/**
|
|
3
|
+
* Tracks which message's "thông tin tin nhắn" (details) modal is open, and derives its
|
|
4
|
+
* "seen by" member list. Returns `null` for the seen-by list (as opposed to an empty
|
|
5
|
+
* array) when the group is too large to compute cheaply, so the modal can render a
|
|
6
|
+
* "too many members" message instead of an empty one.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useMessageDetailsModal(conversationMembers: ConversationMember[] | undefined, isGroup: boolean, groupMemberCount: number): {
|
|
9
|
+
detailsMessage: ChatMessage | null;
|
|
10
|
+
detailsSeenBy: ConversationMember[] | null;
|
|
11
|
+
openDetails: (message: ChatMessage) => void;
|
|
12
|
+
closeDetails: () => void;
|
|
13
|
+
clearIfTarget: (messageId: string) => void;
|
|
14
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
export interface MessageMenuPosition {
|
|
3
|
+
top?: number;
|
|
4
|
+
bottom?: number;
|
|
5
|
+
left: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Tracks which message's options menu ("...") is open and its fixed-position pixel
|
|
9
|
+
* coordinates, clamped inside the message timeline's own bounds (not the browser
|
|
10
|
+
* window, since the chat module is embedded in a host page and may not fill the
|
|
11
|
+
* viewport) so it never overhangs any edge at any container size. Closes on outside
|
|
12
|
+
* click, on timeline scroll, or when its target message is removed.
|
|
13
|
+
*/
|
|
14
|
+
export declare function useMessageMenu(messageTimelineRef: RefObject<HTMLElement | null>): {
|
|
15
|
+
openMessageMenuId: string | null;
|
|
16
|
+
messageMenuPosition: MessageMenuPosition | null;
|
|
17
|
+
openMenu: (messageId: string, triggerRect: DOMRect) => void;
|
|
18
|
+
closeMenu: () => void;
|
|
19
|
+
clearIfTarget: (messageId: string) => void;
|
|
20
|
+
setOpenId: (messageId: string | null) => void;
|
|
21
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ReactionType, ReactionUserItem } from '@medipha/chat-core';
|
|
2
|
+
import { ChatMessage, ConversationMember } from '../../../../utils/chat';
|
|
3
|
+
interface ReactionModalProps {
|
|
4
|
+
message: ChatMessage;
|
|
5
|
+
filter: ReactionType | null;
|
|
6
|
+
items: ReactionUserItem[];
|
|
7
|
+
isLoading: boolean;
|
|
8
|
+
error: string;
|
|
9
|
+
hasMore: boolean;
|
|
10
|
+
onFilterChange: (filter: ReactionType | null) => void;
|
|
11
|
+
onLoadMore: () => void;
|
|
12
|
+
onRetry: () => void;
|
|
13
|
+
onClose: () => void;
|
|
14
|
+
/** So each row can show the same "Phòng ban · Chức vụ" subtitle other member lists
|
|
15
|
+
* show — the reaction detail endpoint itself only returns name/avatar. */
|
|
16
|
+
members: ConversationMember[] | undefined;
|
|
17
|
+
/** Opens the shared account-info modal for a reactor. */
|
|
18
|
+
onOpenProfile: (userId: string) => void;
|
|
19
|
+
}
|
|
20
|
+
/** Shows detail users fetched on demand; message history never supplies these rows. */
|
|
21
|
+
export declare function ReactionModal({ message, filter, items, isLoading, error, hasMore, onFilterChange, onLoadMore, onRetry, onClose, members, onOpenProfile, }: ReactionModalProps): import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ReactionType, ReactionUserItem } from '@medipha/chat-core';
|
|
2
|
+
interface ReactionCursor {
|
|
3
|
+
updatedAt: string | null;
|
|
4
|
+
userId: string | null;
|
|
5
|
+
}
|
|
6
|
+
/** Backs the "who reacted" modal (ReactionModal): which message/filter is showing, its
|
|
7
|
+
* paginated list of reactors, and the API calls that load/refresh/page through it. */
|
|
8
|
+
export declare function useReactionModal(): {
|
|
9
|
+
messageId: string | null;
|
|
10
|
+
filter: ReactionType | null;
|
|
11
|
+
items: ReactionUserItem[];
|
|
12
|
+
cursor: ReactionCursor;
|
|
13
|
+
hasMore: boolean;
|
|
14
|
+
isLoading: boolean;
|
|
15
|
+
error: string;
|
|
16
|
+
open: (targetMessageId: string, targetFilter: ReactionType | null) => void;
|
|
17
|
+
changeFilter: (targetFilter: ReactionType | null) => void;
|
|
18
|
+
loadMore: () => void;
|
|
19
|
+
close: () => void;
|
|
20
|
+
retry: () => void;
|
|
21
|
+
clearIfTarget: (targetMessageId: string) => void;
|
|
22
|
+
};
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Tracks which message's inline emoji reaction picker is open (one at a time). */
|
|
2
|
+
export declare function useReactionPicker(): {
|
|
3
|
+
reactionPickerMessageId: string | null;
|
|
4
|
+
openPicker: (messageId: string | null) => void;
|
|
5
|
+
closePicker: () => void;
|
|
6
|
+
toggle: (messageId: string) => void;
|
|
7
|
+
clearIfTarget: (messageId: string) => void;
|
|
8
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { MessageSystemMemberItem } from '@medipha/chat-core';
|
|
2
|
+
import { ConversationMember } from '../../../../utils/chat';
|
|
3
|
+
interface SystemMembersModalProps {
|
|
4
|
+
totalCount: number;
|
|
5
|
+
/** The verb from the notice itself ("đã thêm" / "đã xóa"), so one modal titles both. */
|
|
6
|
+
actionLabel: string;
|
|
7
|
+
items: MessageSystemMemberItem[];
|
|
8
|
+
isLoading: boolean;
|
|
9
|
+
error: string;
|
|
10
|
+
hasMore: boolean;
|
|
11
|
+
onLoadMore: () => void;
|
|
12
|
+
onRetry: () => void;
|
|
13
|
+
onClose: () => void;
|
|
14
|
+
/** Lets each row show the same "Phòng ban · Chức vụ" subtitle other member lists show — the
|
|
15
|
+
* endpoint itself only returns name/avatar. */
|
|
16
|
+
members: ConversationMember[] | undefined;
|
|
17
|
+
onOpenProfile: (userId: string) => void;
|
|
18
|
+
}
|
|
19
|
+
/** The people a batch "đã thêm" notice named. Same shape as the reaction detail modal: rows
|
|
20
|
+
* are fetched a page at a time, because this list can run to the whole company. */
|
|
21
|
+
export declare function SystemMembersModal({ totalCount, actionLabel, items, isLoading, error, hasMore, onLoadMore, onRetry, onClose, members, onOpenProfile, }: SystemMembersModalProps): import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { MessageSystemMemberItem } from '@medipha/chat-core';
|
|
2
|
+
/** Backs the "N người khác" list on a batch member-add notice: which message is showing, its
|
|
3
|
+
* paginated people, and the calls that load and page through them. The list is never part of
|
|
4
|
+
* the message payload — a 500-member batch would ride along with every history fetch — so it
|
|
5
|
+
* is fetched here the first time someone opens it. */
|
|
6
|
+
export declare function useSystemMembersModal(): {
|
|
7
|
+
messageId: string | null;
|
|
8
|
+
totalCount: number;
|
|
9
|
+
actionLabel: string;
|
|
10
|
+
items: MessageSystemMemberItem[];
|
|
11
|
+
hasMore: boolean;
|
|
12
|
+
isLoading: boolean;
|
|
13
|
+
error: string;
|
|
14
|
+
open: (targetMessageId: string, knownCount: number, label: string) => void;
|
|
15
|
+
loadMore: () => void;
|
|
16
|
+
retry: () => void;
|
|
17
|
+
close: () => void;
|
|
18
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ChatMessage } from '../../utils/chat';
|
|
2
|
+
import { MessageRemovedPayload } from '@medipha/chat-core';
|
|
3
|
+
/**
|
|
4
|
+
* Owns the "thu hồi/gỡ tin nhắn" (remove message) confirm flow: which messages currently
|
|
5
|
+
* have a removal request in flight, and the confirm-dialog-then-API-call sequence itself.
|
|
6
|
+
* Only changes local content after the server confirms via `onRemoved`, which the caller
|
|
7
|
+
* uses to update every UI projection that could still expose the removed message's data.
|
|
8
|
+
*/
|
|
9
|
+
export declare function useMessageRemoval(conversationId: string | undefined, currentUserId: string | null, canModerateMessages: boolean, onRemoved: (removal: MessageRemovedPayload) => void, onConfirmRemoving?: (message: ChatMessage) => void): {
|
|
10
|
+
removalInFlightIds: Set<string>;
|
|
11
|
+
requestRemoval: (message: ChatMessage) => void;
|
|
12
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { VirtuosoHandle } from 'react-virtuoso';
|
|
2
|
+
import { ChatMessage } from '../../utils/chat';
|
|
3
|
+
/**
|
|
4
|
+
* Owns the Virtuoso scroll plumbing for the message timeline: sticky-to-latest pinning
|
|
5
|
+
* across async layout shifts (e.g. images growing after they load), the auto-hiding
|
|
6
|
+
* scrollbar, the floating day-label pill, and the "near bottom" signal used to hide the
|
|
7
|
+
* scroll-to-bottom button a little early. `onScrollStart` is an escape hatch for closing
|
|
8
|
+
* an unrelated popover (the message options menu) that scrolling used to close as a
|
|
9
|
+
* side effect — it isn't this hook's own concern.
|
|
10
|
+
*/
|
|
11
|
+
export declare function useMessageTimelineScroll(messages: ChatMessage[], firstItemIndex: number, onScrollStart?: () => void): {
|
|
12
|
+
virtuosoRef: import('react').RefObject<VirtuosoHandle>;
|
|
13
|
+
timelineScrollerRef: import('react').MutableRefObject<HTMLElement | null>;
|
|
14
|
+
stickToLatestRef: import('react').MutableRefObject<boolean>;
|
|
15
|
+
visibleDayLabel: string | null;
|
|
16
|
+
isNearBottomOfList: boolean;
|
|
17
|
+
scrollToLatest: (behavior?: "auto" | "smooth") => void;
|
|
18
|
+
stickToLatest: () => void;
|
|
19
|
+
handleTimelineScrolling: (scrolling: boolean) => void;
|
|
20
|
+
handleVisibleRangeChanged: (range: {
|
|
21
|
+
startIndex: number;
|
|
22
|
+
endIndex: number;
|
|
23
|
+
}) => void;
|
|
24
|
+
setScrollerRef: (element: unknown) => void;
|
|
25
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ChatMessage, ReactionSummary } from '../../utils/chat';
|
|
2
|
+
import { MessageRemovedPayload } from '@medipha/chat-core';
|
|
3
|
+
type WindowMode = 'latest' | 'around';
|
|
4
|
+
interface WindowMeta {
|
|
5
|
+
oldestSequence: string | null;
|
|
6
|
+
newestSequence: string | null;
|
|
7
|
+
hasOlderMessages: boolean;
|
|
8
|
+
hasNewerMessages: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Owns the paginated message window for one conversation: latest/around loading,
|
|
12
|
+
* older/newer cursor pages, realtime merges, and gap reconciliation.
|
|
13
|
+
*/
|
|
14
|
+
export declare function useMessageWindow(conversationId: string | undefined): {
|
|
15
|
+
clearFocusedMessage: () => void;
|
|
16
|
+
applyMessageRemoved: (removal: MessageRemovedPayload) => void;
|
|
17
|
+
completeAroundFocus: () => void;
|
|
18
|
+
error: string;
|
|
19
|
+
firstItemIndex: number;
|
|
20
|
+
focusedMessageId: string | null;
|
|
21
|
+
focusedMessageIndex: number | null;
|
|
22
|
+
timelineRevision: number;
|
|
23
|
+
handleRealtimeMessage: (incomingMessage: unknown) => void;
|
|
24
|
+
hasUnseenMessages: boolean;
|
|
25
|
+
isAtBottom: boolean;
|
|
26
|
+
isFollowingLatest: () => boolean;
|
|
27
|
+
isRemovedMessageId: (messageId: string) => boolean;
|
|
28
|
+
isLoadingAround: boolean;
|
|
29
|
+
isLoadingLatest: boolean;
|
|
30
|
+
isLoadingNewer: boolean;
|
|
31
|
+
isLoadingOlder: boolean;
|
|
32
|
+
loadAround: (messageId: string) => Promise<boolean>;
|
|
33
|
+
loadLatest: () => Promise<boolean>;
|
|
34
|
+
loadNewer: () => Promise<boolean>;
|
|
35
|
+
loadOlder: () => Promise<boolean>;
|
|
36
|
+
mergeOutgoingMessage: (message: ChatMessage) => void;
|
|
37
|
+
removeOutgoingMessage: (clientMessageId: string) => void;
|
|
38
|
+
messages: ChatMessage[];
|
|
39
|
+
mode: WindowMode;
|
|
40
|
+
reconcile: (afterSequence?: string | null) => Promise<boolean>;
|
|
41
|
+
updateAtBottom: (nextIsAtBottom: boolean) => void;
|
|
42
|
+
updateMessageReactionSummary: (messageId: string, nextReactionSummary: ReactionSummary | ((currentSummary: ReactionSummary) => ReactionSummary)) => void;
|
|
43
|
+
windowMeta: WindowMeta;
|
|
44
|
+
};
|
|
45
|
+
export type MessageWindow = ReturnType<typeof useMessageWindow>;
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
interface PinnedMessagesBarProps {
|
|
3
|
+
conversationId: string | undefined;
|
|
4
|
+
canManagePins: boolean;
|
|
5
|
+
onJump: (messageId: string) => void;
|
|
6
|
+
/** The message-list viewport — the dropdown/scrim portal into it so only the message
|
|
7
|
+
* area dims, leaving the header and composer untouched. */
|
|
8
|
+
timelineRef: RefObject<HTMLElement | null>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Zalo-style pinned bar: a compact strip showing the most recent pin. Expanding it opens
|
|
12
|
+
* a floating dropdown over the conversation (not pushing it down) with the full list.
|
|
13
|
+
* Reads the pinned list straight from the shared pin store (via `usePinnedMessages`) —
|
|
14
|
+
* the same store each message bubble's own pin icon reads, so a pin/unpin from either
|
|
15
|
+
* place shows up in both immediately.
|
|
16
|
+
*/
|
|
17
|
+
export declare function PinnedMessagesBar({ conversationId, canManagePins, onJump: _onJump, timelineRef, }: PinnedMessagesBarProps): import("react/jsx-runtime").JSX.Element | null;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ChatMessage } from '../../utils/chat';
|
|
2
|
+
/**
|
|
3
|
+
* Owns the pinned-messages list for a conversation: fetching it, applying single-message
|
|
4
|
+
* pin/unpin updates (from either the socket ACK or a `message:pinned` broadcast), and
|
|
5
|
+
* emitting the pin toggle itself. `onBeforeToggle` runs before the socket emit — used by
|
|
6
|
+
* the caller to close any unrelated popover (e.g. the reaction picker) that toggling pin
|
|
7
|
+
* used to close as a side effect.
|
|
8
|
+
*
|
|
9
|
+
* Backed by the shared `pinnedMessagesStore` (not local state) — every place that calls
|
|
10
|
+
* this hook for the same conversation (the pinned bar, each message bubble) reads and
|
|
11
|
+
* writes the same list, so a pin/unpin from any of them is reflected everywhere at once.
|
|
12
|
+
*/
|
|
13
|
+
export declare function usePinnedMessages(conversationId: string | undefined, onBeforeToggle?: () => void): {
|
|
14
|
+
pinnedMessages: ChatMessage[];
|
|
15
|
+
pinnedIds: Set<string>;
|
|
16
|
+
applyPinnedUpdate: (message: ChatMessage) => void;
|
|
17
|
+
refreshPinned: () => Promise<void>;
|
|
18
|
+
togglePin: (message: ChatMessage, nextPinned: boolean) => void;
|
|
19
|
+
reset: () => void;
|
|
20
|
+
clearIfTarget: (messageId: string) => void;
|
|
21
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ChatUser, ConversationMember } from '../../utils/chat';
|
|
2
|
+
/**
|
|
3
|
+
* Tracks up to TYPING_INDICATOR_CAP most-recently-active typers for a conversation (most
|
|
4
|
+
* recent first) and auto-clears one if its typing:stop event never arrives. Eviction past
|
|
5
|
+
* the cap is a local display-cap only — it does not emit typing:stop for the evicted user.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useTypingIndicator(isGroup: boolean, otherMember: ConversationMember | undefined, mentionMembers: ChatUser[]): {
|
|
8
|
+
typingNames: string[];
|
|
9
|
+
markUserTyping: (userId: string) => void;
|
|
10
|
+
markUserStoppedTyping: (userId: string) => void;
|
|
11
|
+
resetAll: () => void;
|
|
12
|
+
};
|