stream-chat-react 14.5.0 → 14.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/{ReactPlayerWrapper.963d6170.js → ReactPlayerWrapper.30240f76.js} +2 -2
- package/dist/cjs/{ReactPlayerWrapper.963d6170.js.map → ReactPlayerWrapper.30240f76.js.map} +1 -1
- package/dist/cjs/channel-detail.js +3007 -0
- package/dist/cjs/channel-detail.js.map +1 -0
- package/dist/cjs/emojis.js +5 -4
- package/dist/cjs/emojis.js.map +1 -1
- package/dist/cjs/index.js +1804 -4064
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/useChannelHeaderOnlineStatus.6546ac83.js +4143 -0
- package/dist/cjs/useChannelHeaderOnlineStatus.6546ac83.js.map +1 -0
- package/dist/cjs/useMessageComposerController.c0dad9bc.js +99 -0
- package/dist/cjs/useMessageComposerController.c0dad9bc.js.map +1 -0
- package/dist/cjs/{useNotificationApi.e9312774.js → useNotificationApi.eb753f31.js} +121 -166
- package/dist/cjs/useNotificationApi.eb753f31.js.map +1 -0
- package/dist/css/channel-detail.css +825 -0
- package/dist/css/channel-detail.css.map +1 -0
- package/dist/css/index.css +111 -31
- package/dist/css/index.css.map +1 -1
- package/dist/es/channel-detail.mjs +2950 -0
- package/dist/es/channel-detail.mjs.map +1 -0
- package/dist/es/emojis.mjs +2 -1
- package/dist/es/emojis.mjs.map +1 -1
- package/dist/es/index.mjs +1399 -3669
- package/dist/es/index.mjs.map +1 -1
- package/dist/es/useChannelHeaderOnlineStatus.c5215b13.mjs +3600 -0
- package/dist/es/useChannelHeaderOnlineStatus.c5215b13.mjs.map +1 -0
- package/dist/es/useMessageComposerController.29f189b4.mjs +69 -0
- package/dist/es/useMessageComposerController.29f189b4.mjs.map +1 -0
- package/dist/es/{useNotificationApi.4be515a0.mjs → useNotificationApi.fa5cddf9.mjs} +104 -137
- package/dist/es/useNotificationApi.fa5cddf9.mjs.map +1 -0
- package/dist/types/components/AudioPlayback/components/index.d.ts +1 -0
- package/dist/types/components/AudioPlayback/components/index.d.ts.map +1 -1
- package/dist/types/components/Avatar/ChannelAvatar.d.ts.map +1 -1
- package/dist/types/components/ChannelHeader/hooks/useChannelHasMembersOnline.d.ts +7 -0
- package/dist/types/components/ChannelHeader/hooks/useChannelHasMembersOnline.d.ts.map +1 -0
- package/dist/types/components/ChannelHeader/hooks/useChannelHeaderOnlineStatus.d.ts +6 -1
- package/dist/types/components/ChannelHeader/hooks/useChannelHeaderOnlineStatus.d.ts.map +1 -1
- package/dist/types/components/ChannelListItem/hooks/index.d.ts +1 -0
- package/dist/types/components/ChannelListItem/hooks/index.d.ts.map +1 -1
- package/dist/types/components/ChannelListItem/hooks/useChannelPreviewInfo.d.ts.map +1 -1
- package/dist/types/components/ChannelListItem/hooks/useIsUserMuted.d.ts +2 -0
- package/dist/types/components/ChannelListItem/hooks/useIsUserMuted.d.ts.map +1 -0
- package/dist/types/components/Chat/Chat.d.ts.map +1 -1
- package/dist/types/components/Dialog/components/Prompt.d.ts +7 -4
- package/dist/types/components/Dialog/components/Prompt.d.ts.map +1 -1
- package/dist/types/components/Dialog/service/DialogPortal.d.ts +5 -1
- package/dist/types/components/Dialog/service/DialogPortal.d.ts.map +1 -1
- package/dist/types/components/FileIcon/iconMap.d.ts.map +1 -1
- package/dist/types/components/Form/Checkbox.d.ts +8 -0
- package/dist/types/components/Form/Checkbox.d.ts.map +1 -0
- package/dist/types/components/Form/SwitchField.d.ts +6 -0
- package/dist/types/components/Form/SwitchField.d.ts.map +1 -1
- package/dist/types/components/Form/index.d.ts +1 -0
- package/dist/types/components/Form/index.d.ts.map +1 -1
- package/dist/types/components/Icons/icons.d.ts +12 -0
- package/dist/types/components/Icons/icons.d.ts.map +1 -1
- package/dist/types/components/InfiniteScrollPaginator/index.d.ts +1 -0
- package/dist/types/components/InfiniteScrollPaginator/index.d.ts.map +1 -1
- package/dist/types/components/Message/hooks/useMessageTextStreaming.d.ts +1 -1
- package/dist/types/components/Message/hooks/useReactionsFetcher.d.ts +1 -1
- package/dist/types/components/Message/hooks/useReactionsFetcher.d.ts.map +1 -1
- package/dist/types/components/Modal/GlobalModal.d.ts +3 -1
- package/dist/types/components/Modal/GlobalModal.d.ts.map +1 -1
- package/dist/types/components/Notifications/hooks/useNotificationApi.d.ts.map +1 -1
- package/dist/types/components/Poll/PollCreationDialog/MultipleAnswersField.d.ts.map +1 -1
- package/dist/types/components/Poll/PollOptionSelector.d.ts +0 -4
- package/dist/types/components/Poll/PollOptionSelector.d.ts.map +1 -1
- package/dist/types/context/DialogManagerContext.d.ts +3 -1
- package/dist/types/context/DialogManagerContext.d.ts.map +1 -1
- package/dist/types/i18n/Streami18n.d.ts +99 -0
- package/dist/types/i18n/Streami18n.d.ts.map +1 -1
- package/dist/types/plugins/ChannelDetail/AvatarWithChannelDetail.d.ts +9 -0
- package/dist/types/plugins/ChannelDetail/AvatarWithChannelDetail.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/ChannelDetail.d.ts +14 -0
- package/dist/types/plugins/ChannelDetail/ChannelDetail.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/ChannelDetailContext.d.ts +11 -0
- package/dist/types/plugins/ChannelDetail/ChannelDetailContext.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/ChannelDetailEmptyList.d.ts +3 -0
- package/dist/types/plugins/ChannelDetail/ChannelDetailEmptyList.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/ChannelDetailListLoadingIndicator.d.ts +6 -0
- package/dist/types/plugins/ChannelDetail/ChannelDetailListLoadingIndicator.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/ChannelDetailNavButton.d.ts +15 -0
- package/dist/types/plugins/ChannelDetail/ChannelDetailNavButton.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/ChannelDetailSearchInput.d.ts +8 -0
- package/dist/types/plugins/ChannelDetail/ChannelDetailSearchInput.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/SectionNavigator/SectionNavigator.d.ts +52 -0
- package/dist/types/plugins/ChannelDetail/SectionNavigator/SectionNavigator.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/SectionNavigator/SectionNavigatorHeader.d.ts +11 -0
- package/dist/types/plugins/ChannelDetail/SectionNavigator/SectionNavigatorHeader.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/SectionNavigator/index.d.ts +3 -0
- package/dist/types/plugins/ChannelDetail/SectionNavigator/index.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelFilesView/ChannelFilesEmptyList.d.ts +2 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelFilesView/ChannelFilesEmptyList.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelFilesView/ChannelFilesView.d.ts +5 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelFilesView/ChannelFilesView.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelFilesView/ChannelFilesView.utils.d.ts +40 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelFilesView/ChannelFilesView.utils.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelFilesView/index.d.ts +5 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelFilesView/index.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelFilesView/useChannelFilesSearch.d.ts +10 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelFilesView/useChannelFilesSearch.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelManagementView/ChannelManagementActions.defaults.d.ts +16 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelManagementView/ChannelManagementActions.defaults.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelManagementView/ChannelManagementView.d.ts +20 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelManagementView/ChannelManagementView.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelManagementView/index.d.ts +3 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelManagementView/index.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMediaView/ChannelMediaEmptyList.d.ts +2 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMediaView/ChannelMediaEmptyList.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMediaView/ChannelMediaView.d.ts +8 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMediaView/ChannelMediaView.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMediaView/ChannelMediaView.utils.d.ts +22 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMediaView/ChannelMediaView.utils.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMediaView/index.d.ts +5 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMediaView/index.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMediaView/useChannelMediaSearch.d.ts +9 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMediaView/useChannelMediaSearch.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMemberDetailView/ChannelMemberActions.defaults.d.ts +26 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMemberDetailView/ChannelMemberActions.defaults.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMemberDetailView/ChannelMemberDetail.d.ts +12 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMemberDetailView/ChannelMemberDetail.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMemberDetailView/index.d.ts +3 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMemberDetailView/index.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersAddView.d.ts +7 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersAddView.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersBrowseView.d.ts +6 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersBrowseView.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersHeaderActions.defaults.d.ts +45 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersHeaderActions.defaults.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersView.d.ts +46 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersView.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersView.utils.d.ts +8 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersView.utils.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/index.d.ts +6 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/index.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/useChannelMemberCount.d.ts +4 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/useChannelMemberCount.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/useChannelMemberIds.d.ts +4 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/useChannelMemberIds.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/useChannelMembersSearch.d.ts +12 -0
- package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/useChannelMembersSearch.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/PinnedMessagesView/PinnedMessagesEmptyList.d.ts +2 -0
- package/dist/types/plugins/ChannelDetail/Views/PinnedMessagesView/PinnedMessagesEmptyList.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/PinnedMessagesView/PinnedMessagesView.d.ts +9 -0
- package/dist/types/plugins/ChannelDetail/Views/PinnedMessagesView/PinnedMessagesView.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/PinnedMessagesView/index.d.ts +4 -0
- package/dist/types/plugins/ChannelDetail/Views/PinnedMessagesView/index.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/PinnedMessagesView/usePinnedMessagesCount.d.ts +4 -0
- package/dist/types/plugins/ChannelDetail/Views/PinnedMessagesView/usePinnedMessagesCount.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/Views/PinnedMessagesView/usePinnedMessagesSearch.d.ts +16 -0
- package/dist/types/plugins/ChannelDetail/Views/PinnedMessagesView/usePinnedMessagesSearch.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/VirtualizedList/VirtualizedList.d.ts +28 -0
- package/dist/types/plugins/ChannelDetail/VirtualizedList/VirtualizedList.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/VirtualizedList/index.d.ts +2 -0
- package/dist/types/plugins/ChannelDetail/VirtualizedList/index.d.ts.map +1 -0
- package/dist/types/plugins/ChannelDetail/index.d.ts +16 -0
- package/dist/types/plugins/ChannelDetail/index.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +2 -0
- package/dist/types/utils/index.d.ts.map +1 -1
- package/dist/types/utils/isDmChannel.d.ts +6 -0
- package/dist/types/utils/isDmChannel.d.ts.map +1 -0
- package/package.json +11 -2
- package/dist/cjs/useNotificationApi.e9312774.js.map +0 -1
- package/dist/es/useNotificationApi.4be515a0.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel-detail.js","names":[],"sources":["../../src/plugins/ChannelDetail/SectionNavigator/SectionNavigator.tsx","../../src/plugins/ChannelDetail/SectionNavigator/SectionNavigatorHeader.tsx","../../src/plugins/ChannelDetail/ChannelDetailNavButton.tsx","../../src/plugins/ChannelDetail/ChannelDetailContext.tsx","../../src/plugins/ChannelDetail/Views/ChannelFilesView/ChannelFilesEmptyList.tsx","../../src/plugins/ChannelDetail/ChannelDetailListLoadingIndicator.tsx","../../src/plugins/ChannelDetail/Views/ChannelFilesView/ChannelFilesView.utils.ts","../../src/plugins/ChannelDetail/Views/ChannelFilesView/useChannelFilesSearch.ts","../../src/plugins/ChannelDetail/Views/ChannelFilesView/ChannelFilesView.tsx","../../src/plugins/ChannelDetail/Views/ChannelManagementView/ChannelManagementActions.defaults.tsx","../../src/plugins/ChannelDetail/Views/ChannelManagementView/ChannelManagementView.tsx","../../src/plugins/ChannelDetail/Views/ChannelMediaView/ChannelMediaEmptyList.tsx","../../src/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersView.utils.ts","../../src/plugins/ChannelDetail/Views/ChannelMediaView/ChannelMediaView.utils.ts","../../src/plugins/ChannelDetail/Views/ChannelMediaView/useChannelMediaSearch.ts","../../src/plugins/ChannelDetail/Views/ChannelMediaView/ChannelMediaView.tsx","../../src/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersHeaderActions.defaults.tsx","../../src/plugins/ChannelDetail/VirtualizedList/VirtualizedList.tsx","../../src/plugins/ChannelDetail/Views/ChannelMembersView/useChannelMemberIds.ts","../../src/plugins/ChannelDetail/ChannelDetailSearchInput.tsx","../../src/plugins/ChannelDetail/ChannelDetailEmptyList.tsx","../../src/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersAddView.tsx","../../src/plugins/ChannelDetail/Views/ChannelMembersView/useChannelMemberCount.ts","../../src/plugins/ChannelDetail/Views/ChannelMembersView/useChannelMembersSearch.ts","../../src/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersBrowseView.tsx","../../src/plugins/ChannelDetail/Views/ChannelMemberDetailView/ChannelMemberActions.defaults.tsx","../../src/plugins/ChannelDetail/Views/ChannelMemberDetailView/ChannelMemberDetail.tsx","../../src/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersView.tsx","../../src/plugins/ChannelDetail/Views/PinnedMessagesView/PinnedMessagesEmptyList.tsx","../../src/plugins/ChannelDetail/Views/PinnedMessagesView/usePinnedMessagesCount.ts","../../src/plugins/ChannelDetail/Views/PinnedMessagesView/usePinnedMessagesSearch.ts","../../src/plugins/ChannelDetail/Views/PinnedMessagesView/PinnedMessagesView.tsx","../../src/plugins/ChannelDetail/ChannelDetail.tsx","../../src/plugins/ChannelDetail/AvatarWithChannelDetail.tsx"],"sourcesContent":["import clsx from 'clsx';\nimport React, {\n type ComponentProps,\n type ComponentType,\n createContext,\n type HTMLAttributes,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nexport type SectionNavigatorLayout = string;\n\nexport const SECTION_NAVIGATOR_LAYOUT = {\n inline: 'inline',\n tabs: 'tabs',\n} as const;\n\nexport type SectionNavigatorRoute = {\n id: string;\n};\n\nexport type SectionNavigatorSectionContentProps = {\n layout: SectionNavigatorLayout;\n};\n\nexport type SectionNavigatorNavButtonProps = ComponentProps<'button'> & {\n sectionId: string;\n selected: boolean;\n select: () => void;\n};\n\nexport type SectionNavigatorSection = {\n id: string;\n NavButton: ComponentType<SectionNavigatorNavButtonProps>;\n SectionContent: ComponentType<SectionNavigatorSectionContentProps>;\n};\n\nexport type SectionNavigatorLayoutObserverFactory = ({\n element,\n setLayout,\n tabsLayoutMinWidth,\n}: {\n element: HTMLElement;\n setLayout: (layout: SectionNavigatorLayout) => void;\n tabsLayoutMinWidth: number;\n}) => (() => void) | void;\n\nexport type SectionNavigatorContextValue = {\n layout: SectionNavigatorLayout;\n history: SectionNavigatorRoute[];\n historyPop: () => void;\n historyPush: (route: SectionNavigatorRoute) => void;\n /** Whether the navigation drawer overlay is currently open (inline layout only). */\n isNavigationOpen: boolean;\n /** Opens the navigation drawer overlay (inline layout). */\n openNavigation: () => void;\n /** Closes the navigation drawer overlay (inline layout). */\n closeNavigation: () => void;\n};\n\nexport type SectionNavigatorProps = HTMLAttributes<HTMLDivElement> & {\n sections: SectionNavigatorSection[];\n createLayoutObserver?: SectionNavigatorLayoutObserverFactory;\n defaultLayout?: SectionNavigatorLayout;\n initialHistory?: SectionNavigatorRoute[];\n layout?: SectionNavigatorLayout;\n /** Called whenever the resolved layout changes (and once on mount). */\n onLayoutChange?: (layout: SectionNavigatorLayout) => void;\n tabsLayoutMinWidth?: number;\n};\n\nconst DEFAULT_TABS_LAYOUT_MIN_WIDTH = 640;\n\nconst defaultCreateLayoutObserver: SectionNavigatorLayoutObserverFactory = ({\n element,\n setLayout,\n tabsLayoutMinWidth,\n}) => {\n if (typeof ResizeObserver === 'undefined') return;\n\n const observedElement = element.parentElement ?? element;\n const updateLayout = (width: number) => {\n if (width <= 0) return;\n\n setLayout(\n width < tabsLayoutMinWidth\n ? SECTION_NAVIGATOR_LAYOUT.inline\n : SECTION_NAVIGATOR_LAYOUT.tabs,\n );\n };\n const observer = new ResizeObserver(([entry]) => {\n updateLayout(entry.contentRect.width);\n });\n\n updateLayout(observedElement.getBoundingClientRect().width);\n observer.observe(observedElement);\n\n return () => observer.disconnect();\n};\n\nconst defaultSectionNavigatorContextValue: SectionNavigatorContextValue = {\n closeNavigation: () => undefined,\n history: [],\n historyPop: () => undefined,\n historyPush: () => undefined,\n isNavigationOpen: false,\n layout: SECTION_NAVIGATOR_LAYOUT.tabs,\n openNavigation: () => undefined,\n};\n\nconst SectionNavigatorContext = createContext<SectionNavigatorContextValue>(\n defaultSectionNavigatorContextValue,\n);\n\nexport const useSectionNavigatorContext = () => useContext(SectionNavigatorContext);\n\nconst getCurrentRoute = (history: SectionNavigatorRoute[]) => history[history.length - 1];\n\nexport const SectionNavigator = ({\n className,\n createLayoutObserver = defaultCreateLayoutObserver,\n defaultLayout = SECTION_NAVIGATOR_LAYOUT.tabs,\n initialHistory,\n layout: controlledLayout,\n onLayoutChange,\n sections,\n tabsLayoutMinWidth = DEFAULT_TABS_LAYOUT_MIN_WIDTH,\n ...props\n}: SectionNavigatorProps) => {\n const rootRef = useRef<HTMLDivElement | null>(null);\n const [internalLayout, setInternalLayout] =\n useState<SectionNavigatorLayout>(defaultLayout);\n const [history, setHistory] = useState<SectionNavigatorRoute[]>(\n () => initialHistory ?? (sections[0] ? [{ id: sections[0].id }] : []),\n );\n const [isNavigationOpen, setIsNavigationOpen] = useState(false);\n const layout = controlledLayout ?? internalLayout;\n const currentRoute = getCurrentRoute(history);\n const currentSection = sections.find((section) => section.id === currentRoute?.id);\n const activeSection = currentSection ?? sections[0];\n const isInlineLayout = layout === SECTION_NAVIGATOR_LAYOUT.inline;\n const showDockedNavigation = !isInlineLayout || !currentSection;\n\n const openNavigation = useCallback(() => setIsNavigationOpen(true), []);\n const closeNavigation = useCallback(() => setIsNavigationOpen(false), []);\n\n const historyPush = useCallback(\n (route: SectionNavigatorRoute) => {\n setHistory((history) => {\n const currentRoute = getCurrentRoute(history);\n\n if (currentRoute?.id === route.id) return history;\n if (layout === SECTION_NAVIGATOR_LAYOUT.tabs) return [route];\n\n return [...history, route];\n });\n },\n [layout],\n );\n\n const historyPop = useCallback(() => {\n setHistory((history) => (history.length > 1 ? history.slice(0, -1) : history));\n }, []);\n\n // The drawer overlay only exists in inline layout; close it whenever we leave\n // inline so it cannot linger after a resize to a wider layout.\n useEffect(() => {\n if (!isInlineLayout) setIsNavigationOpen(false);\n }, [isInlineLayout]);\n\n useEffect(() => {\n if (!isNavigationOpen) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') closeNavigation();\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [closeNavigation, isNavigationOpen]);\n\n useEffect(() => {\n onLayoutChange?.(layout);\n }, [layout, onLayoutChange]);\n\n useEffect(() => {\n if (controlledLayout) return;\n if (!rootRef.current) return;\n\n return createLayoutObserver({\n element: rootRef.current,\n setLayout: setInternalLayout,\n tabsLayoutMinWidth,\n });\n }, [controlledLayout, createLayoutObserver, tabsLayoutMinWidth]);\n\n useEffect(() => {\n setHistory((history) => {\n const currentRoute = getCurrentRoute(history);\n const currentRouteHasSection = sections.some(\n (section) => section.id === currentRoute?.id,\n );\n\n if (!currentRoute) return sections[0] ? [{ id: sections[0].id }] : [];\n\n if (currentRouteHasSection) return history;\n\n return sections[0] ? [{ id: sections[0].id }] : [];\n });\n }, [sections]);\n\n const contextValue = useMemo<SectionNavigatorContextValue>(\n () => ({\n closeNavigation,\n history,\n historyPop,\n historyPush,\n isNavigationOpen,\n layout,\n openNavigation,\n }),\n [\n closeNavigation,\n history,\n historyPop,\n historyPush,\n isNavigationOpen,\n layout,\n openNavigation,\n ],\n );\n\n const Content = activeSection?.SectionContent;\n\n const navigation = (\n <div className='str-chat__section-navigator__navigation'>\n {sections.map((section) => {\n const NavButton = section.NavButton;\n const selected = activeSection?.id === section.id;\n\n return (\n <div className='str-chat__section-navigator__navigation-item' key={section.id}>\n <NavButton\n className='str-chat__section-navigator__navigation-item__nav-button'\n sectionId={section.id}\n select={() => {\n historyPush({ id: section.id });\n closeNavigation();\n }}\n selected={selected}\n />\n </div>\n );\n })}\n </div>\n );\n\n return (\n <SectionNavigatorContext.Provider value={contextValue}>\n <div\n className={clsx('str-chat__section-navigator', className, {\n 'str-chat__section-navigator--inline': isInlineLayout,\n })}\n data-layout={layout}\n ref={rootRef}\n {...props}\n >\n {showDockedNavigation && navigation}\n {Content && (\n <div className='str-chat__section-navigator__content'>\n <Content layout={layout} />\n </div>\n )}\n {isInlineLayout && (\n <div\n className={clsx('str-chat__section-navigator__navigation-overlay', {\n 'str-chat__section-navigator__navigation-overlay--open': isNavigationOpen,\n })}\n >\n <button\n aria-hidden\n className='str-chat__section-navigator__navigation-scrim'\n onClick={closeNavigation}\n tabIndex={-1}\n type='button'\n />\n <div className='str-chat__section-navigator__navigation-drawer'>\n {navigation}\n </div>\n </div>\n )}\n </div>\n </SectionNavigatorContext.Provider>\n );\n};\n","import React, { useMemo } from 'react';\n\nimport { SECTION_NAVIGATOR_LAYOUT, useSectionNavigatorContext } from './SectionNavigator';\nimport { useTranslationContext } from '../../../context';\nimport { Button } from '../../../components/Button';\nimport { Prompt, type PromptHeaderProps } from '../../../components/Dialog';\nimport { IconMenu } from '../../../components/Icons';\n\nexport type SectionNavigatorHeaderProps = Omit<PromptHeaderProps, 'LeadingContent'>;\n\n/**\n * Generic header for content rendered inside a `SectionNavigator`. It renders a\n * `Prompt.Header` and, in the inline layout (where the navigation sidebar is not\n * shown), prepends a hamburger button that opens the navigation drawer. The\n * hamburger is omitted on nested views that already show a back button\n * (`goBack`), where it would compete with the back affordance.\n */\nexport const SectionNavigatorHeader = (props: SectionNavigatorHeaderProps) => {\n const { t } = useTranslationContext('SectionNavigatorHeader');\n const { layout, openNavigation } = useSectionNavigatorContext();\n\n const MenuButton = useMemo(() => {\n if (layout !== SECTION_NAVIGATOR_LAYOUT.inline) return undefined;\n if (props.goBack) return undefined;\n\n return function SectionNavigatorHeaderMenuButton() {\n return (\n <Button\n appearance='ghost'\n aria-label={t('Open menu')}\n circular\n className='str-chat__section-navigator__header-menu-button'\n onClick={openNavigation}\n size='md'\n variant='secondary'\n >\n <IconMenu />\n </Button>\n );\n };\n }, [layout, openNavigation, props.goBack, t]);\n\n return <Prompt.Header {...props} LeadingContent={MenuButton} />;\n};\n","import React, { type ComponentType } from 'react';\n\nimport type { SectionNavigatorNavButtonProps } from './SectionNavigator';\nimport { ListItemLayout } from '../../components/ListItemLayout';\nimport clsx from 'clsx';\n\nexport type ChannelDetailNavButtonProps = SectionNavigatorNavButtonProps & {\n /** Icon rendered as the leading element of the nav button. */\n LeadingIcon: ComponentType;\n /** Label displayed for the section. */\n title: string;\n};\n\n/**\n * Underlying button shared by all ChannelDetail section nav buttons. Renders a\n * `ListItemLayout` as a `<button>` and wires the SectionNavigator selection\n * state into `aria-current` and the click handler.\n */\nexport const ChannelDetailNavButton = ({\n className,\n LeadingIcon,\n // Dropped so it is not forwarded onto the DOM <button> via `...props`.\n sectionId: _sectionId, // eslint-disable-line @typescript-eslint/no-unused-vars\n select,\n selected,\n title,\n ...props\n}: ChannelDetailNavButtonProps) => (\n <ListItemLayout\n LeadingIcon={LeadingIcon}\n RootElement='button'\n rootProps={{\n ...props,\n 'aria-current': selected ? ('page' as const) : undefined,\n className: clsx('str-chat__channel-detail__nav-button', className),\n onClick: select,\n }}\n selected={selected}\n title={title}\n />\n);\n","import type { PropsWithChildren } from 'react';\nimport React, { useContext, useMemo } from 'react';\nimport type { Channel } from 'stream-chat';\n\nexport type ChannelDetailContextValue = {\n channel: Channel;\n};\n\nconst ChannelDetailContext = React.createContext<ChannelDetailContextValue | undefined>(\n undefined,\n);\n\nexport type ChannelDetailProviderProps = PropsWithChildren<{\n channel: Channel;\n}>;\n\nexport const ChannelDetailProvider = ({\n channel,\n children,\n}: ChannelDetailProviderProps) => {\n const value = useMemo(() => ({ channel }), [channel]);\n\n return (\n <ChannelDetailContext.Provider value={value}>\n {children}\n </ChannelDetailContext.Provider>\n );\n};\n\nexport const useChannelDetailContext = () => {\n const contextValue = useContext(ChannelDetailContext);\n\n if (!contextValue) {\n throw new Error(\n 'The useChannelDetailContext hook was called outside of ChannelDetailProvider.',\n );\n }\n\n return contextValue;\n};\n","import { useTranslationContext } from '../../../../context';\nimport { IconFolder } from '../../../../components/Icons';\n\nexport const ChannelFilesEmptyList = () => {\n const { t } = useTranslationContext('ChannelFilesEmptyList');\n\n return (\n <div className='str-chat__channel-detail__files-view__empty-state'>\n <IconFolder className='str-chat__channel-detail__files-view__empty-state__icon' />\n <div className='str-chat__channel-detail__files-view__empty-state__content'>\n <p className='str-chat__channel-detail__files-view__empty-state__title'>\n {t('No files')}\n </p>\n <p className='str-chat__channel-detail__files-view__empty-state__description'>\n {t('Share a file to see it here')}\n </p>\n </div>\n </div>\n );\n};\n","import type { SearchSource, SearchSourceState } from 'stream-chat';\nimport { useStateStore } from '../../store';\nimport { LoadingIndicator } from '../../components/Loading';\n\nconst searchSourceFooterStateSelector = (state: SearchSourceState) => ({\n hasNextPage: state.hasNext,\n isLoading: state.isLoading,\n});\n\nexport type ChannelMembersViewListFooterProps<T> = {\n searchSource: SearchSource<T>;\n};\n\nexport const ChannelDetailListLoadingIndicator = <T,>({\n searchSource,\n}: ChannelMembersViewListFooterProps<T>) => {\n const { hasNextPage, isLoading } = useStateStore(\n searchSource.state,\n searchSourceFooterStateSelector,\n );\n\n if (!hasNextPage || !isLoading) return null;\n\n return (\n <div className='str-chat__loading-indicator-placeholder'>\n {isLoading && <LoadingIndicator />}\n </div>\n );\n};\n","import {\n type Attachment,\n isScrapedContent,\n type LocalMessage,\n type MessageResponse,\n} from 'stream-chat';\n\nimport { isDate } from '../../../../i18n/utils';\n\n/** Attachment types listed by the files view (everything that is not an image/video). */\nexport const FILE_ATTACHMENT_TYPES = ['file', 'audio'] as const;\n\nexport type ChannelFileAttachmentType = (typeof FILE_ATTACHMENT_TYPES)[number];\n\nconst FILE_ATTACHMENT_TYPE_SET = new Set<string>(FILE_ATTACHMENT_TYPES);\n\nexport type ChannelFileItem = {\n /** Raw attachment to render (no transformation applied). */\n attachment: Attachment;\n /** Stable identity (messageId + attachment index). */\n id: string;\n /** ISO timestamp of the carrying message, used for the month sections. */\n createdAt?: string;\n};\n\nexport type ChannelFileSection = {\n /** Stable grouping key (`YYYY-MM` or `unknown`). */\n key: string;\n /** Representative timestamp used to render the section header. */\n timestamp?: string;\n};\n\nexport type ChannelFileSections = {\n /**\n * Item counts per section, aligned 1:1 with `sections`. Maps directly onto\n * GroupedVirtuoso's `groupCounts`; `sum(groupCounts) === items.length`.\n */\n groupCounts: number[];\n /** Flat list of items in display order, grouped contiguously by section. */\n items: ChannelFileItem[];\n /** Section headers (month/year), aligned 1:1 with `groupCounts`. */\n sections: ChannelFileSection[];\n};\n\nconst normalizeTimestamp = (timestamp?: string | Date) => {\n if (!timestamp) return undefined;\n return isDate(timestamp) ? timestamp.toISOString() : timestamp;\n};\n\nconst isChannelFileAttachment = (attachment: Attachment) =>\n !isScrapedContent(attachment) &&\n !!attachment.type &&\n FILE_ATTACHMENT_TYPE_SET.has(attachment.type);\n\nconst byCreatedAtDesc = (a: ChannelFileItem, b: ChannelFileItem) =>\n (b.createdAt ?? '').localeCompare(a.createdAt ?? '');\n\n/**\n * Flattens messages into file/audio attachment items organized into descending\n * month/year sections (newest first), in a single pass over the attachments.\n *\n * The result is shaped for GroupedVirtuoso: a single flat `items` array (items\n * grouped contiguously by section) plus `groupCounts`/`sections` aligned with\n * it, so the view never has to re-flatten. The raw attachment is kept\n * untransformed; only the carrying message timestamp is captured for headers.\n */\nexport const toChannelFileSections = (\n messages: Array<MessageResponse | LocalMessage>,\n): ChannelFileSections => {\n const groups: Array<ChannelFileSection & { items: ChannelFileItem[] }> = [];\n const groupIndexByKey = new Map<string, number>();\n\n messages.forEach((message) => {\n const createdAt = normalizeTimestamp(message.created_at);\n const key = createdAt ? createdAt.slice(0, 7) : 'unknown';\n\n message.attachments?.forEach((attachment, index) => {\n if (!isChannelFileAttachment(attachment)) return;\n\n const item: ChannelFileItem = {\n attachment,\n createdAt,\n id: `${message.id}-${index}`,\n };\n const existingIndex = groupIndexByKey.get(key);\n\n if (existingIndex === undefined) {\n groupIndexByKey.set(key, groups.length);\n groups.push({ items: [item], key, timestamp: createdAt });\n } else {\n groups[existingIndex].items.push(item);\n }\n });\n });\n\n groups.forEach((group) => {\n group.items.sort(byCreatedAtDesc);\n group.timestamp = group.items[0]?.createdAt;\n });\n groups.sort((a, b) => (b.timestamp ?? '').localeCompare(a.timestamp ?? ''));\n\n return {\n groupCounts: groups.map((group) => group.items.length),\n items: groups.flatMap((group) => group.items),\n sections: groups.map(({ key, timestamp }) => ({ key, timestamp })),\n };\n};\n","import {\n type LocalMessage,\n type MessageResponse,\n MessageSearchSource,\n type SearchSourceState,\n} from 'stream-chat';\nimport { useEffect, useMemo } from 'react';\n\nimport { useChatContext } from '../../../../context';\nimport { useStateStore } from '../../../../store';\nimport { useChannelDetailContext } from '../../ChannelDetailContext';\nimport { FILE_ATTACHMENT_TYPES, toChannelFileSections } from './ChannelFilesView.utils';\n\nconst CHANNEL_FILES_SEARCH_PAGE_SIZE = 30;\n\nconst channelFilesSearchSourceStateSelector = (\n state: SearchSourceState<MessageResponse>,\n) => ({\n isLoading: state.isLoading,\n messages: state.items,\n});\n\nexport const useChannelFilesSearch = () => {\n const { client } = useChatContext();\n const { channel } = useChannelDetailContext();\n\n const channelFilesSearchSource = useMemo(() => {\n const source = new MessageSearchSource(client, {\n allowEmptySearchString: true,\n pageSize: CHANNEL_FILES_SEARCH_PAGE_SIZE,\n resetOnNewSearchQuery: false,\n });\n\n source.messageSearchChannelFilters = { cid: channel.cid };\n source.messageSearchFilters = {\n 'attachments.type': { $in: [...FILE_ATTACHMENT_TYPES] },\n };\n\n return source;\n }, [channel.cid, client]);\n\n const { isLoading, messages } = useStateStore(\n channelFilesSearchSource.state,\n channelFilesSearchSourceStateSelector,\n );\n\n const { groupCounts, items, sections } = useMemo(\n () =>\n toChannelFileSections((messages ?? []) as Array<MessageResponse | LocalMessage>),\n [messages],\n );\n\n useEffect(() => {\n channelFilesSearchSource.activate();\n void channelFilesSearchSource.search('');\n\n return () => {\n channelFilesSearchSource.cancelScheduledQuery();\n };\n }, [channelFilesSearchSource]);\n\n return {\n channelFilesSearchSource,\n fileItems: items,\n groupCounts,\n hasResultsLoaded: Array.isArray(messages),\n isLoading,\n sections,\n };\n};\n","import clsx from 'clsx';\nimport type { ComponentProps } from 'react';\nimport React, { forwardRef, useCallback, useMemo } from 'react';\nimport { GroupedVirtuoso } from 'react-virtuoso';\n\nimport { useModalContext, useTranslationContext } from '../../../../context';\nimport { getDateString } from '../../../../i18n/utils';\nimport { FileSizeIndicator } from '../../../../components/Attachment/components/FileSizeIndicator';\nimport { Prompt } from '../../../../components/Dialog';\nimport { FileIcon } from '../../../../components/FileIcon';\nimport { ListItemLayout } from '../../../../components/ListItemLayout';\nimport {\n SectionNavigatorHeader,\n type SectionNavigatorSectionContentProps,\n} from '../../SectionNavigator';\nimport { ChannelDetailListLoadingIndicator } from '../../ChannelDetailListLoadingIndicator';\nimport { ChannelFilesEmptyList } from './ChannelFilesEmptyList';\nimport type { ChannelFileItem } from './ChannelFilesView.utils';\nimport { useChannelFilesSearch } from './useChannelFilesSearch';\n\n// Wraps each virtualized file row so the horizontal inset can be applied to a\n// stable class without padding the full-bleed sticky month headers.\nconst ChannelFilesItem = forwardRef<HTMLDivElement, ComponentProps<'div'>>(\n function ChannelFilesItem({ className, ...props }, ref) {\n return (\n <div\n {...props}\n className={clsx('str-chat__channel-detail__files-view__item', className)}\n ref={ref}\n />\n );\n },\n);\n\n// Wraps each sticky month header. react-virtuoso applies `position: sticky` but\n// leaves `top: auto`, so the headers never pin to the scroller top and\n// consecutive months overlap; the class supplies the required `top: 0`.\nconst ChannelFilesGroup = forwardRef<HTMLDivElement, ComponentProps<'div'>>(\n function ChannelFilesGroup({ className, ...props }, ref) {\n return (\n <div\n {...props}\n className={clsx('str-chat__channel-detail__files-view__group', className)}\n ref={ref}\n />\n );\n },\n);\n\nconst ChannelFilesSectionHeader = ({ timestamp }: { timestamp?: string }) => {\n const { t, tDateTimeParser } = useTranslationContext('ChannelFilesView');\n const label = getDateString({\n format: 'MMMM YYYY',\n messageCreatedAt: timestamp,\n t,\n tDateTimeParser,\n });\n\n if (!label) return null;\n\n return (\n <div className='str-chat__channel-detail__files-view__section-header'>{label}</div>\n );\n};\n\nconst getAttachmentFileName = (attachment: ChannelFileItem['attachment']) =>\n attachment.title || attachment.fallback || '';\n\nconst ChannelFileListItem = ({ item }: { item: ChannelFileItem }) => {\n const { attachment } = item;\n const fileName = getAttachmentFileName(attachment);\n const assetUrl = attachment.asset_url;\n\n const LeadingSlot = useMemo(\n () =>\n function FileListItemIcon() {\n return (\n <FileIcon\n className='str-chat__channel-detail__files-view__list-item__icon'\n fileName={fileName}\n mimeType={attachment.mime_type}\n size='md'\n />\n );\n },\n [attachment.mime_type, fileName],\n );\n\n const sharedProps = useMemo(\n () => ({\n LeadingSlot,\n subtitle: <FileSizeIndicator fileSize={attachment.file_size} />,\n subtitleClassName: 'str-chat__channel-detail__files-view__list-item__size',\n title: fileName,\n titleClassName: 'str-chat__channel-detail__files-view__list-item__name',\n }),\n [attachment.file_size, fileName, LeadingSlot],\n );\n\n const linkRootProps = useMemo(\n () => ({\n className: 'str-chat__channel-detail__files-view__list-item',\n download: fileName || undefined,\n href: assetUrl,\n rel: 'noopener noreferrer',\n target: '_blank',\n }),\n [assetUrl, fileName],\n );\n\n const divRootProps = useMemo(\n () => ({ className: 'str-chat__channel-detail__files-view__list-item' }),\n [],\n );\n\n if (assetUrl) {\n return <ListItemLayout {...sharedProps} RootElement='a' rootProps={linkRootProps} />;\n }\n\n return <ListItemLayout {...sharedProps} RootElement='div' rootProps={divRootProps} />;\n};\n\nexport type ChannelFilesViewProps = SectionNavigatorSectionContentProps;\n\nexport const ChannelFilesView: React.ComponentType<ChannelFilesViewProps> = () => {\n const { t } = useTranslationContext();\n const { close } = useModalContext();\n const { channelFilesSearchSource, fileItems, groupCounts, hasResultsLoaded, sections } =\n useChannelFilesSearch();\n\n const groupContent = useCallback(\n (groupIndex: number) => (\n <ChannelFilesSectionHeader timestamp={sections[groupIndex]?.timestamp} />\n ),\n [sections],\n );\n\n // In grouped mode the `index` passed here is the flat item index (0-based\n // across all items, excluding group headers), so it indexes `fileItems`\n // directly. We intentionally don't pass `computeItemKey`: GroupedVirtuoso\n // calls it with the absolute group+item location index (and no item data),\n // so it can't be used to look items up — the default position keys are\n // correct for this append-only list.\n const itemContent = useCallback(\n (index: number) => <ChannelFileListItem item={fileItems[index]} />,\n [fileItems],\n );\n\n const atBottomStateChange = useCallback(\n (atBottom: boolean) => {\n if (atBottom) channelFilesSearchSource.search();\n },\n [channelFilesSearchSource],\n );\n\n const EmptyPlaceholder = useMemo(\n () =>\n function ChannelFilesEmptyPlaceholder() {\n return hasResultsLoaded ? <ChannelFilesEmptyList /> : null;\n },\n [hasResultsLoaded],\n );\n\n const Footer = useMemo(\n () =>\n function ChannelFilesListFooter() {\n return (\n <ChannelDetailListLoadingIndicator searchSource={channelFilesSearchSource} />\n );\n },\n [channelFilesSearchSource],\n );\n\n const components = useMemo(\n () => ({\n EmptyPlaceholder,\n Footer,\n Group: ChannelFilesGroup,\n Item: ChannelFilesItem,\n }),\n [EmptyPlaceholder, Footer],\n );\n\n return (\n <div className='str-chat__channel-detail__files-view'>\n <SectionNavigatorHeader close={close} title={t('Files')} />\n <Prompt.Body className='str-chat__channel-detail__files-view__body'>\n <GroupedVirtuoso\n atBottomStateChange={atBottomStateChange}\n className='str-chat__virtualized-list str-chat__channel-detail__files-view__list'\n components={components}\n groupContent={groupContent}\n groupCounts={groupCounts}\n itemContent={itemContent}\n />\n </Prompt.Body>\n </div>\n );\n};\n","import React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport debounce from 'lodash.debounce';\nimport type { Channel } from 'stream-chat';\n\nimport {\n useChatContext,\n useComponentContext,\n useModalContext,\n useTranslationContext,\n} from '../../../../context';\nimport { isDmChannel, useStableCallback } from '../../../../utils';\nimport { useIsChannelMuted } from '../../../../components/ChannelListItem/hooks/useIsChannelMuted';\nimport { useStateStore } from '../../../../store';\nimport { Alert } from '../../../../components/Dialog';\nimport { Button } from '../../../../components/Button';\nimport { Switch } from '../../../../components/Form';\nimport {\n IconAudio,\n IconDelete,\n IconLeave,\n IconMute,\n IconNoSign,\n} from '../../../../components/Icons';\nimport { ListItemLayout } from '../../../../components/ListItemLayout';\nimport { GlobalModal } from '../../../../components/Modal';\nimport { useNotificationApi } from '../../../../components/Notifications';\nimport { useChannelDetailContext } from '../../ChannelDetailContext';\nimport clsx from 'clsx';\n\nexport type ChannelManagementActionType =\n | 'blockUser'\n | 'deleteChat'\n | 'leaveChannel'\n | 'muteChannel'\n | 'muteUser'\n | (string & {});\n\nexport type ChannelManagementActionItem = {\n Component: React.ComponentType;\n type: ChannelManagementActionType;\n};\n\nconst toError = (error: unknown) =>\n error instanceof Error ? error : new Error('An unknown error occurred');\n\nconst getDisplayName = (name?: string, fallback?: string) => name || fallback || '';\n\nconst BlockUserActionIcon = () => (\n <IconNoSign className='str-chat__icon--destructive str-chat__channel-detail__action-icon str-chat__channel-detail__action-icon--block-user' />\n);\nconst DeleteChatActionIcon = () => (\n <IconDelete className='str-chat__icon--destructive str-chat__channel-detail__action-icon str-chat__channel-detail__action-icon--delete-chat' />\n);\nconst MuteActionIcon = () => (\n <IconMute className='str-chat__channel-detail__action-icon str-chat__channel-detail__action-icon--mute' />\n);\nconst MutedActionIcon = () => (\n <IconAudio className='str-chat__channel-detail__action-icon str-chat__channel-detail__action-icon--unmute' />\n);\nconst LeaveChannelActionIcon = () => (\n <IconLeave className='str-chat__icon--destructive str-chat__channel-detail__action-icon str-chat__channel-detail__action-icon--leave-channel' />\n);\n\nconst channelManagementViewActionClassName = 'str-chat__channel-management-view-action';\n\nconst blockedUsersSelector = ({ userIds }: { userIds: string[] }) => ({ userIds });\n\ntype ChannelManagementConfirmationAlertProps = {\n action: 'blockUser' | 'deleteChat' | 'leaveChannel';\n cancelLabel: string;\n confirmLabel: string;\n description: string;\n isSubmitting?: boolean;\n onCancel: () => void;\n onConfirm: () => void;\n testId: string;\n title: string;\n};\n\nconst ChannelManagementConfirmationAlert = ({\n action,\n cancelLabel,\n confirmLabel,\n description,\n isSubmitting,\n onCancel,\n onConfirm,\n testId,\n title,\n}: ChannelManagementConfirmationAlertProps) => (\n <Alert.Root\n className={clsx('str-chat__channel-management-confirmation-alert', {\n [`str-chat__channel-management-confirmation-alert--${action}`]: action,\n })}\n data-testid={testId}\n >\n <Alert.Header description={description} title={title} />\n <Alert.Actions>\n <Button\n appearance='solid'\n data-testid={`${testId}-confirm-button`}\n disabled={isSubmitting}\n onClick={onConfirm}\n size='md'\n variant='danger'\n >\n {confirmLabel}\n </Button>\n <Button\n appearance='outline'\n autoFocus\n data-testid={`${testId}-cancel-button`}\n disabled={isSubmitting}\n onClick={onCancel}\n size='md'\n variant='secondary'\n >\n {cancelLabel}\n </Button>\n </Alert.Actions>\n </Alert.Root>\n);\n\nconst useOtherMember = () => {\n const { client } = useChatContext();\n const { channel } = useChannelDetailContext();\n\n return useMemo(() => {\n const stateMembers = Object.values(channel.state?.members ?? {});\n const members = stateMembers.length ? stateMembers : (channel.data?.members ?? []);\n\n return members.find(\n (member) => member.user?.id && member.user.id !== client.user?.id,\n );\n }, [channel, client.user?.id]);\n};\n\nconst useChannelManagementActionFilterState = () => {\n const { client } = useChatContext();\n const { channel } = useChannelDetailContext();\n const otherMember = useOtherMember();\n const resolvedIsDmChannel = isDmChannel({\n channel,\n ownUserId: client.user?.id,\n });\n const isGroupChannel = !resolvedIsDmChannel;\n const ownCapabilities = channel.data?.own_capabilities;\n const isDmChannelWithOtherUser = resolvedIsDmChannel && !!otherMember;\n\n return {\n canBlockUser:\n isDmChannelWithOtherUser && ownCapabilities?.includes('ban-channel-members'),\n canDeleteChat: ownCapabilities?.includes('delete-channel'),\n canLeaveChannel: isGroupChannel && ownCapabilities?.includes('leave-channel'),\n canMuteChannel: ownCapabilities?.includes('mute-channel'),\n canMuteUser: isDmChannelWithOtherUser,\n };\n};\n\nexport const useBaseChannelManagementActionSetFilter = (\n channelManagementActionSet: ChannelManagementActionItem[],\n) => {\n const { canBlockUser, canDeleteChat, canLeaveChannel, canMuteChannel, canMuteUser } =\n useChannelManagementActionFilterState();\n\n return useMemo(\n () =>\n channelManagementActionSet.filter((action) => {\n switch (action.type) {\n case 'blockUser':\n return canBlockUser;\n case 'deleteChat':\n return canDeleteChat;\n case 'muteChannel':\n return canMuteChannel;\n case 'muteUser':\n return canMuteUser;\n case 'leaveChannel':\n return canLeaveChannel;\n default:\n return true;\n }\n }),\n [\n canBlockUser,\n canDeleteChat,\n canLeaveChannel,\n canMuteChannel,\n canMuteUser,\n channelManagementActionSet,\n ],\n );\n};\n\nconst ChannelMuteAction = () => {\n const { channel } = useChannelDetailContext();\n const { addNotification } = useNotificationApi();\n const { t } = useTranslationContext();\n const { muted: channelMuted } = useIsChannelMuted(channel);\n const [optimisticChannelMuted, setOptimisticChannelMuted] = useState(channelMuted);\n\n useEffect(() => {\n setOptimisticChannelMuted(channelMuted);\n }, [channelMuted]);\n\n const toggleChannelMuteRequest = useStableCallback(\n (nextMuted: boolean, targetChannel: Channel) => {\n if (!nextMuted) {\n return targetChannel\n .unmute()\n .then(() =>\n addNotification({\n context: { channel: targetChannel },\n emitter: 'ChannelManagementView',\n message: t('Channel unmuted'),\n severity: 'success',\n type: 'api:channel:unmute:success',\n }),\n )\n .catch((error) => {\n // Reconcile to the truth source rather than a hard-coded value: with\n // the debounced request, optimistic state may have flipped multiple\n // times, so a fixed boolean can land on the wrong state.\n setOptimisticChannelMuted(channelMuted);\n\n return addNotification({\n context: { channel: targetChannel },\n emitter: 'ChannelManagementView',\n error: toError(error),\n message: t('Error unmuting channel'),\n severity: 'error',\n type: 'api:channel:unmute:failed',\n });\n });\n }\n\n return targetChannel\n .mute()\n .then(() =>\n addNotification({\n context: { channel: targetChannel },\n emitter: 'ChannelManagementView',\n message: t('Channel muted'),\n severity: 'success',\n type: 'api:channel:mute:success',\n }),\n )\n .catch((error) => {\n setOptimisticChannelMuted(channelMuted);\n\n return addNotification({\n context: { channel: targetChannel },\n emitter: 'ChannelManagementView',\n error: toError(error),\n message: t('Error muting channel'),\n severity: 'error',\n type: 'api:channel:mute:failed',\n });\n });\n },\n );\n\n const toggleChannelMute = useMemo(\n () => debounce(toggleChannelMuteRequest, 1000),\n [toggleChannelMuteRequest],\n );\n\n useEffect(\n () => () => {\n toggleChannelMute.cancel();\n },\n [toggleChannelMute],\n );\n\n const toggleOptimisticChannelMute = useCallback(() => {\n const nextMuted = !optimisticChannelMuted;\n\n setOptimisticChannelMuted(nextMuted);\n toggleChannelMute(nextMuted, channel);\n }, [channel, optimisticChannelMuted, toggleChannelMute]);\n\n const rootProps = useMemo(\n () => ({\n 'aria-pressed': optimisticChannelMuted,\n className: clsx(\n 'str-chat__form__switch-field',\n channelManagementViewActionClassName,\n ),\n onClick: toggleOptimisticChannelMute,\n }),\n [optimisticChannelMuted, toggleOptimisticChannelMute],\n );\n\n const TrailingSlot = useMemo(() => {\n function ChannelMuteSwitch() {\n return <Switch on={optimisticChannelMuted} presentation />;\n }\n\n return ChannelMuteSwitch;\n }, [optimisticChannelMuted]);\n\n return (\n <ListItemLayout\n LeadingIcon={optimisticChannelMuted ? MutedActionIcon : MuteActionIcon}\n RootElement='button'\n rootProps={rootProps}\n title={optimisticChannelMuted ? t('Unmute chat') : t('Mute chat')}\n TrailingSlot={TrailingSlot}\n />\n );\n};\n\nconst UserMuteAction = () => {\n const { client, mutes } = useChatContext();\n const { channel } = useChannelDetailContext();\n const { addNotification } = useNotificationApi();\n const { t } = useTranslationContext();\n const otherMember = useOtherMember();\n const userMuted = !!mutes.find((mute) => mute.target.id === otherMember?.user?.id);\n const [optimisticUserMuted, setOptimisticUserMuted] = useState(userMuted);\n\n useEffect(() => {\n setOptimisticUserMuted(userMuted);\n }, [userMuted]);\n\n const otherMemberUserId = otherMember?.user?.id;\n const toggleUserMuteRequest = useStableCallback(\n (nextMuted: boolean, targetUserId?: string) => {\n if (!targetUserId) return;\n\n if (!nextMuted) {\n return client\n .unmuteUser(targetUserId)\n .then(() =>\n addNotification({\n context: { channel },\n emitter: 'ChannelManagementView',\n message: t('User unmuted'),\n severity: 'success',\n type: 'api:user:unmute:success',\n }),\n )\n .catch((error) => {\n // Reconcile to the truth source rather than a hard-coded value: with\n // the debounced request, optimistic state may have flipped multiple\n // times, so a fixed boolean can land on the wrong state.\n setOptimisticUserMuted(userMuted);\n\n return addNotification({\n context: { channel },\n emitter: 'ChannelManagementView',\n error: toError(error),\n message: t('Error unmuting user'),\n severity: 'error',\n type: 'api:user:unmute:failed',\n });\n });\n }\n\n return client\n .muteUser(targetUserId)\n .then(() =>\n addNotification({\n context: { channel },\n emitter: 'ChannelManagementView',\n message: t('User muted'),\n severity: 'success',\n type: 'api:user:mute:success',\n }),\n )\n .catch((error) => {\n setOptimisticUserMuted(userMuted);\n\n return addNotification({\n context: { channel },\n emitter: 'ChannelManagementView',\n error: toError(error),\n message: t('Error muting user'),\n severity: 'error',\n type: 'api:user:mute:failed',\n });\n });\n },\n );\n\n const toggleUserMute = useMemo(\n () => debounce(toggleUserMuteRequest, 1000),\n [toggleUserMuteRequest],\n );\n\n useEffect(\n () => () => {\n toggleUserMute.cancel();\n },\n [toggleUserMute],\n );\n\n const toggleOptimisticUserMute = useCallback(() => {\n const nextMuted = !optimisticUserMuted;\n\n setOptimisticUserMuted(nextMuted);\n toggleUserMute(nextMuted, otherMemberUserId);\n }, [optimisticUserMuted, otherMemberUserId, toggleUserMute]);\n\n const rootProps = useMemo(\n () => ({\n 'aria-pressed': optimisticUserMuted,\n className: clsx(\n 'str-chat__form__switch-field',\n channelManagementViewActionClassName,\n ),\n onClick: toggleOptimisticUserMute,\n }),\n [optimisticUserMuted, toggleOptimisticUserMute],\n );\n const TrailingSlot = useMemo(() => {\n function UserMuteSwitch() {\n return <Switch on={optimisticUserMuted} presentation />;\n }\n\n return UserMuteSwitch;\n }, [optimisticUserMuted]);\n\n return (\n <ListItemLayout\n LeadingIcon={optimisticUserMuted ? MutedActionIcon : MuteActionIcon}\n RootElement='button'\n rootProps={rootProps}\n title={optimisticUserMuted ? t('Unmute user') : t('Mute user')}\n TrailingSlot={TrailingSlot}\n />\n );\n};\n\nconst BlockUserAction = () => {\n const { client } = useChatContext();\n const { Modal = GlobalModal } = useComponentContext();\n const { channel } = useChannelDetailContext();\n const { addNotification } = useNotificationApi();\n const { t } = useTranslationContext();\n const otherMember = useOtherMember();\n const targetUserId = otherMember?.user?.id;\n const { userIds: blockedUserIds } = useStateStore(\n client.blockedUsers,\n blockedUsersSelector,\n );\n const isBlocked = useMemo(\n () => !!targetUserId && new Set(blockedUserIds).has(targetUserId),\n [blockedUserIds, targetUserId],\n );\n const [alertOpen, setAlertOpen] = useState(false);\n const [userBlockInProgress, setUserBlockInProgress] = useState(false);\n\n const closeBlockUserAlert = useCallback(() => {\n setAlertOpen(false);\n }, []);\n\n const openBlockUserAlert = useCallback(() => {\n setAlertOpen(true);\n }, []);\n\n const unblockUser = useCallback(async () => {\n if (!targetUserId) return;\n\n try {\n setUserBlockInProgress(true);\n await client.unBlockUser(targetUserId);\n addNotification({\n context: { channel },\n emitter: 'ChannelManagementView',\n message: t('User unblocked'),\n severity: 'success',\n type: 'api:user:unblock:success',\n });\n } catch (error) {\n addNotification({\n context: { channel },\n emitter: 'ChannelManagementView',\n error: toError(error),\n message: t('Error unblocking user'),\n severity: 'error',\n type: 'api:user:unblock:failed',\n });\n } finally {\n setAlertOpen(false);\n setUserBlockInProgress(false);\n }\n }, [addNotification, channel, client, targetUserId, t]);\n\n const blockUser = useCallback(async () => {\n if (!targetUserId) return;\n\n try {\n setUserBlockInProgress(true);\n await client.blockUser(targetUserId);\n addNotification({\n context: { channel },\n emitter: 'ChannelManagementView',\n message: t('User blocked'),\n severity: 'success',\n type: 'api:user:block:success',\n });\n } catch (error) {\n addNotification({\n context: { channel },\n emitter: 'ChannelManagementView',\n error: toError(error),\n message: t('Error blocking user'),\n severity: 'error',\n type: 'api:user:block:failed',\n });\n } finally {\n setAlertOpen(false);\n setUserBlockInProgress(false);\n }\n }, [addNotification, channel, client, targetUserId, t]);\n\n const rootProps = useMemo(\n () => ({\n className: channelManagementViewActionClassName,\n disabled: userBlockInProgress,\n onClick: openBlockUserAlert,\n }),\n [openBlockUserAlert, userBlockInProgress],\n );\n\n return (\n <>\n <ListItemLayout\n destructive\n LeadingIcon={BlockUserActionIcon}\n RootElement='button'\n rootProps={rootProps}\n title={isBlocked ? t('Unblock') : t('Block user')}\n />\n <Modal open={alertOpen} role='alertdialog'>\n <ChannelManagementConfirmationAlert\n action='blockUser'\n cancelLabel={t('Cancel')}\n confirmLabel={isBlocked ? t('Unblock') : t('Block User')}\n description={\n isBlocked\n ? t('This user will be able to message you again.')\n : t(\n \"This user won't be able to message you anymore. You can unblock them anytime.\",\n )\n }\n isSubmitting={userBlockInProgress}\n onCancel={closeBlockUserAlert}\n onConfirm={isBlocked ? unblockUser : blockUser}\n testId='channel-detail-block-user-alert'\n title={isBlocked ? t('Unblock') : t('Block User')}\n />\n </Modal>\n </>\n );\n};\n\nconst LeaveChannelAction = () => {\n const { client } = useChatContext();\n const { channel } = useChannelDetailContext();\n const { Modal = GlobalModal } = useComponentContext();\n const { close } = useModalContext();\n const { addNotification } = useNotificationApi();\n const { t } = useTranslationContext();\n const [alertOpen, setAlertOpen] = useState(false);\n const [leaveChannelInProgress, setLeaveChannelInProgress] = useState(false);\n\n const closeLeaveChannelAlert = useCallback(() => {\n setAlertOpen(false);\n }, []);\n\n const openLeaveChannelAlert = useCallback(() => {\n setAlertOpen(true);\n }, []);\n\n const leaveChannel = useCallback(async () => {\n if (!client.userID) return;\n\n try {\n setLeaveChannelInProgress(true);\n await channel.removeMembers([client.userID]);\n addNotification({\n context: { channel },\n emitter: 'ChannelManagementView',\n message: t('Left channel'),\n severity: 'success',\n type: 'api:channel:leave:success',\n });\n setAlertOpen(false);\n close();\n } catch (error) {\n addNotification({\n context: { channel },\n emitter: 'ChannelManagementView',\n error: toError(error),\n message: t('Failed to leave channel'),\n severity: 'error',\n type: 'api:channel:leave:failed',\n });\n } finally {\n setLeaveChannelInProgress(false);\n }\n }, [addNotification, channel, client.userID, close, t]);\n\n const rootProps = useMemo(\n () => ({\n className: channelManagementViewActionClassName,\n disabled: leaveChannelInProgress,\n onClick: openLeaveChannelAlert,\n }),\n [leaveChannelInProgress, openLeaveChannelAlert],\n );\n\n return (\n <>\n <ListItemLayout\n destructive\n LeadingIcon={LeaveChannelActionIcon}\n RootElement='button'\n rootProps={rootProps}\n title={t('Leave chat')}\n />\n <Modal open={alertOpen} role='alertdialog'>\n <ChannelManagementConfirmationAlert\n action='leaveChannel'\n cancelLabel={t('Cancel')}\n confirmLabel={t('Leave chat')}\n description={t('Are you sure you want to leave this channel?')}\n isSubmitting={leaveChannelInProgress}\n onCancel={closeLeaveChannelAlert}\n onConfirm={leaveChannel}\n testId='channel-detail-leave-channel-alert'\n title={t('Leave chat')}\n />\n </Modal>\n </>\n );\n};\n\nconst DeleteChatAction = () => {\n const { channel } = useChannelDetailContext();\n const { Modal = GlobalModal } = useComponentContext();\n const { close: closeChannelDetail } = useModalContext();\n const { addNotification } = useNotificationApi();\n const { t } = useTranslationContext();\n const otherMember = useOtherMember();\n const [alertOpen, setAlertOpen] = useState(false);\n const [deleteChatInProgress, setDeleteChatInProgress] = useState(false);\n const userName = getDisplayName(otherMember?.user?.name, otherMember?.user?.id);\n\n const closeDeleteChatAlert = useCallback(() => {\n setAlertOpen(false);\n }, []);\n\n const openDeleteChatAlert = useCallback(() => {\n setAlertOpen(true);\n }, []);\n\n const deleteChat = useCallback(async () => {\n try {\n setDeleteChatInProgress(true);\n await channel.delete();\n addNotification({\n context: { channel },\n emitter: 'ChannelManagementView',\n message: t('Chat deleted'),\n severity: 'success',\n type: 'api:channel:delete:success',\n });\n setAlertOpen(false);\n closeChannelDetail();\n } catch (error) {\n addNotification({\n context: { channel },\n emitter: 'ChannelManagementView',\n error: toError(error),\n message: t('Error deleting chat'),\n severity: 'error',\n type: 'api:channel:delete:failed',\n });\n } finally {\n setDeleteChatInProgress(false);\n }\n }, [addNotification, channel, closeChannelDetail, t]);\n\n const rootProps = useMemo(\n () => ({\n className: channelManagementViewActionClassName,\n disabled: deleteChatInProgress,\n onClick: openDeleteChatAlert,\n }),\n [deleteChatInProgress, openDeleteChatAlert],\n );\n\n return (\n <>\n <ListItemLayout\n destructive\n LeadingIcon={DeleteChatActionIcon}\n RootElement='button'\n rootProps={rootProps}\n title={t('Delete chat')}\n />\n <Modal open={alertOpen} role='alertdialog'>\n <ChannelManagementConfirmationAlert\n action='deleteChat'\n cancelLabel={t('Cancel')}\n confirmLabel={t('Delete chat')}\n description={t(\n \"This permanently deletes your message history with {{ user }}. This can't be undone.\",\n { user: userName },\n )}\n isSubmitting={deleteChatInProgress}\n onCancel={closeDeleteChatAlert}\n onConfirm={deleteChat}\n testId='channel-detail-delete-chat-alert'\n title={t('Delete chat')}\n />\n </Modal>\n </>\n );\n};\n\nexport const DefaultChannelManagementActions = {\n BlockUser: BlockUserAction,\n DeleteChat: DeleteChatAction,\n LeaveChannel: LeaveChannelAction,\n MuteChannel: ChannelMuteAction,\n MuteUser: UserMuteAction,\n};\n\nexport const defaultChannelManagementActionSet: ChannelManagementActionItem[] = [\n {\n Component: DefaultChannelManagementActions.MuteChannel,\n type: 'muteChannel',\n },\n {\n Component: DefaultChannelManagementActions.MuteUser,\n type: 'muteUser',\n },\n {\n Component: DefaultChannelManagementActions.BlockUser,\n type: 'blockUser',\n },\n {\n Component: DefaultChannelManagementActions.LeaveChannel,\n type: 'leaveChannel',\n },\n {\n Component: DefaultChannelManagementActions.DeleteChat,\n type: 'deleteChat',\n },\n];\n","import React, {\n type SyntheticEvent,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport {\n useChatContext,\n useComponentContext,\n useModalContext,\n useTranslationContext,\n} from '../../../../context';\nimport { isDmChannel } from '../../../../utils';\nimport {\n SectionNavigatorHeader,\n type SectionNavigatorSectionContentProps,\n} from '../../SectionNavigator';\nimport { ChannelAvatar as DefaultChannelAvatar } from '../../../../components/Avatar';\nimport {\n useChannelPreviewInfo,\n useIsUserMuted,\n} from '../../../../components/ChannelListItem';\nimport { IconCheckmark, IconMute, IconPin } from '../../../../components/Icons';\nimport { useChannelMembershipState } from '../../../../components/ChannelList';\nimport { useIsChannelMuted } from '../../../../components/ChannelListItem/hooks/useIsChannelMuted';\nimport { useChannelHasMembersOnline } from '../../../../components/ChannelHeader/hooks/useChannelHasMembersOnline';\nimport { Prompt } from '../../../../components/Dialog';\nimport {\n type ChannelManagementActionItem,\n defaultChannelManagementActionSet,\n useBaseChannelManagementActionSetFilter,\n} from './ChannelManagementActions.defaults';\nimport { useChannelHeaderOnlineStatus } from '../../../../components/ChannelHeader/hooks/useChannelHeaderOnlineStatus';\nimport { useChannelDetailContext } from '../../ChannelDetailContext';\nimport { Button } from '../../../../components/Button';\nimport { TextInput } from '../../../../components/Form';\nimport { useNotificationApi } from '../../../../components/Notifications/hooks/useNotificationApi';\n\nexport type ChannelManagementViewProps = SectionNavigatorSectionContentProps & {\n channelManagementActionSet?: ChannelManagementActionItem[];\n EditModeComponent?: React.ComponentType<ChannelManagementEditBodyProps>;\n uploadImage?: ChannelManagementImageUpload;\n ViewModeComponent?: React.ComponentType<ChannelManagementInfoBodyProps>;\n};\n\nexport type ChannelManagementImageUpload = (file: File) => Promise<string> | string;\n\nexport type ChannelManagementInfoBodyProps = {\n actions: ChannelManagementActionItem[];\n};\n\nexport const ChannelManagementInfoBody = ({\n actions,\n}: ChannelManagementInfoBodyProps) => {\n const { client } = useChatContext();\n const { channel } = useChannelDetailContext();\n const { Avatar = DefaultChannelAvatar } = useComponentContext();\n const { displayImage, displayTitle, groupChannelDisplayInfo } = useChannelPreviewInfo({\n channel,\n });\n const resolvedIsDmChannel = isDmChannel({\n channel,\n ownUserId: client.user?.id,\n });\n const otherMemberUserId = useMemo(() => {\n if (!resolvedIsDmChannel) return;\n\n return Object.values(channel.state?.members ?? {}).find(\n (member) => member.user?.id && member.user.id !== client.user?.id,\n )?.user?.id;\n }, [channel, client.user?.id, resolvedIsDmChannel]);\n const isOnline = useChannelHasMembersOnline({ channel });\n const { muted: channelMuted } = useIsChannelMuted(channel);\n const userMuted = useIsUserMuted(otherMemberUserId);\n const membership = useChannelMembershipState(channel);\n const onlineStatusText = useChannelHeaderOnlineStatus({ channel });\n const pinned = !!membership.pinned_at;\n\n return (\n <Prompt.Body className='str-chat__channel-detail__channel-management-view__body'>\n <div className='str-chat__channel-detail__channel-management-view__profile'>\n <Avatar\n displayMembers={groupChannelDisplayInfo.members}\n imageUrl={displayImage}\n isOnline={resolvedIsDmChannel ? isOnline : undefined}\n size='2xl'\n userName={displayTitle}\n />\n <div className='str-chat__channel-detail__channel-management-view__profile__details'>\n <div className='str-chat__channel-detail__channel-management-view__profile__details__title'>\n {displayTitle && <span>{displayTitle}</span>}\n {pinned && <IconPin />}\n {(resolvedIsDmChannel && userMuted) ||\n (!resolvedIsDmChannel && channelMuted) ? (\n <IconMute />\n ) : null}\n </div>\n {onlineStatusText && (\n <div className='str-chat__channel-detail__channel-management-view__profile__details__connection-status'>\n {onlineStatusText}\n </div>\n )}\n </div>\n </div>\n\n <div className='str-chat__channel-detail__channel-management-view__actions str-chat__form__switch-fieldset'>\n {actions.map(({ Component, type }) => (\n <Component key={type} />\n ))}\n </div>\n </Prompt.Body>\n );\n};\n\nexport type ChannelManagementEditBodyProps = {\n uploadImage?: ChannelManagementImageUpload;\n};\n\nconst EDIT_BODY_EMITTER = 'ChannelManagementEditBody';\n\ntype ChannelUpdatePayload = {\n set?: { image?: string; name?: string };\n unset?: ['image'];\n};\n\n/**\n * Assembles the argument for `channel.updatePartial` from the pending edits,\n * or returns `null` when there is nothing to persist. `image` is a tri-state:\n * a string sets a new avatar, `null` clears it, `undefined` leaves it untouched.\n */\nconst buildChannelUpdatePayload = ({\n image,\n name,\n}: {\n image?: string | null;\n name?: string;\n}): ChannelUpdatePayload | null => {\n const payload: ChannelUpdatePayload = {};\n\n const set: { image?: string; name?: string } = {};\n if (name !== undefined) set.name = name;\n if (typeof image === 'string') set.image = image;\n if (Object.keys(set).length > 0) payload.set = set;\n\n if (image === null) payload.unset = ['image'];\n\n return Object.keys(payload).length > 0 ? payload : null;\n};\n\n/**\n * Owns the channel-edit form: field state, the local image preview lifecycle,\n * the derived \"can save\" flags, and the save orchestration (upload → persist →\n * notify). The component is left to render the values this returns.\n */\nconst useChannelManagementEditForm = ({\n uploadImage,\n}: ChannelManagementEditBodyProps) => {\n const { t } = useTranslationContext();\n const { client } = useChatContext();\n const { channel } = useChannelDetailContext();\n const { displayImage, displayTitle, groupChannelDisplayInfo } = useChannelPreviewInfo({\n channel,\n });\n const { addNotification } = useNotificationApi();\n\n const resolvedIsDmChannel = isDmChannel({ channel, ownUserId: client.user?.id });\n const hasMembersOnline = useChannelHasMembersOnline({ channel });\n const isOnline = resolvedIsDmChannel ? hasMembersOnline : undefined;\n const nameLabel = resolvedIsDmChannel ? t('Contact name') : t('Group name');\n\n // Dirty-tracking baseline; advanced to the saved value on success so the form\n // is no longer considered dirty (and the Save button hides) after a write.\n const [baselineName, setBaselineName] = useState(channel.data?.name ?? '');\n const [name, setName] = useState(baselineName);\n // null = keep current avatar, File = replace it, 'removed' = clear it\n const [imageEdit, setImageEdit] = useState<File | 'removed' | null>(null);\n const [isSaving, setIsSaving] = useState(false);\n\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const pickedFile = imageEdit instanceof File ? imageEdit : null;\n\n // Preview the locally picked file, releasing the object URL when it changes or unmounts.\n const objectUrl = useMemo(\n () => (pickedFile ? URL.createObjectURL(pickedFile) : null),\n [pickedFile],\n );\n\n useEffect(\n () => () => {\n if (objectUrl) URL.revokeObjectURL(objectUrl);\n },\n [objectUrl],\n );\n\n const previewImageUrl =\n objectUrl ?? (imageEdit === 'removed' ? undefined : displayImage);\n\n const trimmedName = name.trim();\n const nameChanged = trimmedName !== baselineName.trim();\n const imageChanged = imageEdit !== null;\n const hasChanges = (trimmedName.length > 0 && nameChanged) || imageChanged;\n const canSubmit = trimmedName.length > 0 && !isSaving && hasChanges;\n\n const handleOpenFilePicker = useCallback(() => {\n fileInputRef.current?.click();\n }, []);\n\n const handleFileChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0];\n if (file) setImageEdit(file);\n event.target.value = '';\n }, []);\n\n const handleDeleteImage = useCallback(() => setImageEdit('removed'), []);\n\n const resolveImageUrl = useCallback(\n async (file: File) => {\n const url = uploadImage\n ? await uploadImage(file)\n : (await channel.sendImage(file)).file;\n if (!url) throw new Error('Image upload did not return a URL');\n return url;\n },\n [channel, uploadImage],\n );\n\n const handleSubmit = useCallback(\n async (event: SyntheticEvent<HTMLFormElement>) => {\n event.preventDefault();\n if (!canSubmit) return;\n\n setIsSaving(true);\n try {\n let image: string | null | undefined;\n if (pickedFile) image = await resolveImageUrl(pickedFile);\n else if (imageEdit === 'removed') image = null;\n\n const payload = buildChannelUpdatePayload({\n image,\n name: nameChanged ? trimmedName : undefined,\n });\n if (payload) await channel.updatePartial(payload);\n\n // Clear the dirty state so an identical re-save isn't offered.\n setImageEdit(null);\n setBaselineName(trimmedName);\n setName(trimmedName);\n\n addNotification({\n duration: 3000,\n emitter: EDIT_BODY_EMITTER,\n incident: {\n domain: 'channel',\n entity: 'channel',\n operation: 'update',\n status: 'success',\n },\n message: t('Changes saved'),\n severity: 'success',\n });\n } catch (error) {\n addNotification({\n emitter: EDIT_BODY_EMITTER,\n error: error instanceof Error ? error : undefined,\n incident: {\n domain: 'api',\n entity: 'channel',\n operation: 'update',\n status: 'failed',\n },\n message: t('Failed to save changes'),\n severity: 'error',\n });\n } finally {\n setIsSaving(false);\n }\n },\n [\n addNotification,\n canSubmit,\n channel,\n imageEdit,\n nameChanged,\n pickedFile,\n resolveImageUrl,\n t,\n trimmedName,\n ],\n );\n\n return {\n canSubmit,\n displayTitle,\n fileInputRef,\n groupChannelDisplayInfo,\n handleDeleteImage,\n handleFileChange,\n handleOpenFilePicker,\n handleSubmit,\n hasAvatarImage: !!previewImageUrl,\n isOnline,\n name,\n nameLabel,\n previewImageUrl,\n setName,\n t,\n trimmedName,\n };\n};\n\nexport const ChannelManagementEditBody = (props: ChannelManagementEditBodyProps) => {\n const { Avatar = DefaultChannelAvatar } = useComponentContext();\n const {\n canSubmit,\n displayTitle,\n fileInputRef,\n groupChannelDisplayInfo,\n handleDeleteImage,\n handleFileChange,\n handleOpenFilePicker,\n handleSubmit,\n hasAvatarImage,\n isOnline,\n name,\n nameLabel,\n previewImageUrl,\n setName,\n t,\n trimmedName,\n } = useChannelManagementEditForm(props);\n\n return (\n <form\n className='str-chat__channel-detail__channel-management-view__form'\n onSubmit={handleSubmit}\n >\n <Prompt.Body className='str-chat__channel-detail__channel-management-view__body'>\n <div className='str-chat__channel-detail__channel-management-view__avatar-row'>\n <Avatar\n displayMembers={groupChannelDisplayInfo.members}\n imageUrl={previewImageUrl}\n isOnline={isOnline}\n size='2xl'\n userName={trimmedName || displayTitle}\n />\n <div className='str-chat__channel-detail__channel-management-view__avatar-row__actions'>\n <Button\n appearance='outline'\n onClick={handleOpenFilePicker}\n size='sm'\n type='button'\n variant='secondary'\n >\n {t('Upload Picture')}\n </Button>\n {hasAvatarImage && (\n <Button\n appearance='outline'\n onClick={handleDeleteImage}\n size='sm'\n type='button'\n variant='secondary'\n >\n {t('Delete')}\n </Button>\n )}\n <input\n accept='image/*'\n aria-hidden\n className='str-chat__channel-detail__channel-management-view__file-input'\n onChange={handleFileChange}\n ref={fileInputRef}\n tabIndex={-1}\n type='file'\n />\n </div>\n </div>\n\n <TextInput\n aria-label={nameLabel}\n autoFocus\n className='str-chat__channel-detail__channel-management-view__name-input'\n maxLength={255}\n onChange={(event) => setName(event.target.value)}\n placeholder={nameLabel}\n value={name}\n />\n </Prompt.Body>\n\n <Prompt.Footer className='str-chat__channel-detail__channel-management-view__footer'>\n <Prompt.FooterControls>\n {canSubmit && (\n <Prompt.FooterControlsButtonPrimary\n className='str-chat__channel-detail__channel-management-view__footer__save-button'\n type='submit'\n >\n <IconCheckmark />\n {t('Save')}\n </Prompt.FooterControlsButtonPrimary>\n )}\n </Prompt.FooterControls>\n </Prompt.Footer>\n </form>\n );\n};\n\nexport const ChannelManagementView = ({\n channelManagementActionSet = defaultChannelManagementActionSet,\n EditModeComponent = ChannelManagementEditBody,\n uploadImage,\n ViewModeComponent = ChannelManagementInfoBody,\n}: ChannelManagementViewProps) => {\n const { t } = useTranslationContext();\n const { client } = useChatContext();\n const { channel } = useChannelDetailContext();\n const { close } = useModalContext();\n const resolvedIsDmChannel = isDmChannel({\n channel,\n ownUserId: client.user?.id,\n });\n const actions = useBaseChannelManagementActionSetFilter(channelManagementActionSet);\n const [isEditing, setIsEditing] = useState(false);\n const canEditChannel = channel.data?.own_capabilities?.includes('update-channel');\n // Edit mode requires the capability: revoking it (or swapping channels) must\n // drop back to view mode so the form cannot keep editing/submitting.\n const isEditMode = isEditing && canEditChannel;\n\n useEffect(() => {\n setIsEditing(false);\n }, [channel.cid]);\n\n const EditChannelButton = useMemo(\n () =>\n function EditChannelButton() {\n return (\n <Button\n appearance='outline'\n aria-label={t('Edit chat data')}\n className='str-chat__channel-detail__channel-management-view__edit-button'\n onClick={() => {\n setIsEditing(true);\n }}\n size='md'\n variant='secondary'\n >\n {t('Edit')}\n </Button>\n );\n },\n [t],\n );\n\n const headerTitle = isEditMode\n ? resolvedIsDmChannel\n ? t('Edit contact')\n : t('Edit group')\n : resolvedIsDmChannel\n ? t('Contact info')\n : t('Group info');\n\n return (\n <div className='str-chat__channel-detail__channel-management-view'>\n <SectionNavigatorHeader\n close={close}\n description={isEditMode ? undefined : t('Manage channel')}\n goBack={isEditMode ? () => setIsEditing(false) : undefined}\n title={headerTitle}\n TrailingContent={!isEditMode && canEditChannel ? EditChannelButton : undefined}\n />\n {isEditMode ? (\n <EditModeComponent uploadImage={uploadImage} />\n ) : (\n <ViewModeComponent actions={actions} />\n )}\n </div>\n );\n};\n","import { useTranslationContext } from '../../../../context';\nimport { IconImage } from '../../../../components/Icons';\n\nexport const ChannelMediaEmptyList = () => {\n const { t } = useTranslationContext('ChannelMediaEmptyList');\n\n return (\n <div className='str-chat__channel-detail__media-view__empty-state'>\n <IconImage className='str-chat__channel-detail__media-view__empty-state__icon' />\n <div className='str-chat__channel-detail__media-view__empty-state__content'>\n <p className='str-chat__channel-detail__media-view__empty-state__title'>\n {t('No photos or videos')}\n </p>\n <p className='str-chat__channel-detail__media-view__empty-state__description'>\n {t('Share a photo or video to see it here')}\n </p>\n </div>\n </div>\n );\n};\n","import { type Channel, type ChannelMemberResponse, type UserResponse } from 'stream-chat';\n\nexport const CHANNEL_MEMBERS_QUERY_LIMIT = 100;\n\nexport const getMemberDisplayName = (member: ChannelMemberResponse) =>\n getUserDisplayName(member.user) || member.user_id || '';\n\nexport const getMemberUserId = (member: ChannelMemberResponse) =>\n member.user?.id || member.user_id;\n\nexport const getUserDisplayName = (user?: UserResponse) =>\n user?.name || user?.username || user?.id || '';\n\nexport const getChannelMemberUserIds = (channel: Channel) =>\n Object.values(channel.state?.members ?? {})\n .map((member) => member.user?.id || member.user_id)\n .filter((userId): userId is string => !!userId);\n\nexport const canUpdateChannelMembers = (channel: Channel) =>\n channel.data?.own_capabilities?.includes('update-channel-members') ?? false;\n","import {\n type Attachment,\n isImageAttachment,\n isVideoAttachment,\n type LocalMessage,\n type MessageResponse,\n type UserResponse,\n} from 'stream-chat';\n\nimport { toBaseImageDescriptors } from '../../../../components/BaseImage';\nimport type { GalleryItem } from '../../../../components/Gallery';\n\n/** Attachment types rendered by the media gallery. */\nexport const MEDIA_ATTACHMENT_TYPES = ['image', 'video'] as const;\n\nexport type ChannelMediaItemType = (typeof MEDIA_ATTACHMENT_TYPES)[number];\n\nexport type ChannelMediaItem = {\n /** Item to hand over to the full-screen `Gallery` viewer. */\n galleryItem: GalleryItem;\n /** Stable identity (messageId + attachment index). */\n id: string;\n type: ChannelMediaItemType;\n /** Video duration in seconds, when known. */\n durationSeconds?: number;\n /** User who shared the media. */\n user?: UserResponse;\n};\n\nconst getMediaAttachmentType = (\n attachment: Attachment,\n): ChannelMediaItemType | undefined => {\n if (isVideoAttachment(attachment)) return 'video';\n if (isImageAttachment(attachment)) return 'image';\n return undefined;\n};\n\n/**\n * Flattens messages into one renderable media item per image/video attachment,\n * carrying over the gallery descriptor, posting user, and video duration.\n */\nexport const toChannelMediaItems = (\n messages: Array<MessageResponse | LocalMessage>,\n): ChannelMediaItem[] => {\n const items: ChannelMediaItem[] = [];\n\n messages.forEach((message) => {\n message.attachments?.forEach((attachment, index) => {\n const type = getMediaAttachmentType(attachment);\n if (!type) return;\n\n const descriptor = toBaseImageDescriptors(attachment);\n if (!descriptor) return;\n\n const hasRenderableSource =\n type === 'video'\n ? Boolean(descriptor.videoThumbnailUrl || descriptor.videoUrl)\n : Boolean(descriptor.imageUrl);\n if (!hasRenderableSource) return;\n\n items.push({\n durationSeconds:\n typeof attachment.duration === 'number' ? attachment.duration : undefined,\n galleryItem: descriptor,\n id: `${message.id}-${index}`,\n type,\n user: message.user ?? undefined,\n });\n });\n });\n\n return items;\n};\n","import {\n type LocalMessage,\n type MessageResponse,\n MessageSearchSource,\n type SearchSourceState,\n} from 'stream-chat';\nimport { useEffect, useMemo } from 'react';\n\nimport { useChatContext } from '../../../../context';\nimport { useStateStore } from '../../../../store';\nimport { useChannelDetailContext } from '../../ChannelDetailContext';\nimport { MEDIA_ATTACHMENT_TYPES, toChannelMediaItems } from './ChannelMediaView.utils';\n\nconst CHANNEL_MEDIA_SEARCH_PAGE_SIZE = 30;\n\nconst channelMediaSearchSourceItemsStateSelector = (\n state: SearchSourceState<MessageResponse>,\n) => ({\n hasNext: state.hasNext,\n isLoading: state.isLoading,\n messages: state.items,\n});\n\nexport const useChannelMediaSearch = () => {\n const { client } = useChatContext();\n const { channel } = useChannelDetailContext();\n\n const channelMediaSearchSource = useMemo(() => {\n const source = new MessageSearchSource(client, {\n allowEmptySearchString: true,\n pageSize: CHANNEL_MEDIA_SEARCH_PAGE_SIZE,\n resetOnNewSearchQuery: false,\n });\n\n source.messageSearchChannelFilters = { cid: channel.cid };\n source.messageSearchFilters = {\n 'attachments.type': { $in: [...MEDIA_ATTACHMENT_TYPES] },\n };\n\n return source;\n }, [channel.cid, client]);\n\n const { hasNext, isLoading, messages } = useStateStore(\n channelMediaSearchSource.state,\n channelMediaSearchSourceItemsStateSelector,\n );\n\n const mediaItems = useMemo(\n () => toChannelMediaItems((messages ?? []) as Array<MessageResponse | LocalMessage>),\n [messages],\n );\n\n useEffect(() => {\n channelMediaSearchSource.activate();\n void channelMediaSearchSource.search('');\n\n return () => {\n channelMediaSearchSource.cancelScheduledQuery();\n };\n }, [channelMediaSearchSource]);\n\n return {\n channelMediaSearchSource,\n hasNext: Boolean(hasNext),\n hasResultsLoaded: Array.isArray(messages),\n isLoading,\n mediaItems,\n };\n};\n","import clsx from 'clsx';\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport {\n useComponentContext,\n useModalContext,\n useTranslationContext,\n} from '../../../../context';\nimport { formatTime } from '../../../../components/AudioPlayback';\nimport { Avatar } from '../../../../components/Avatar';\nimport { Badge } from '../../../../components/Badge';\nimport {\n type BaseImageProps,\n BaseImage as DefaultBaseImage,\n} from '../../../../components/BaseImage';\nimport { Prompt } from '../../../../components/Dialog';\nimport { Gallery as DefaultGallery, GalleryUI } from '../../../../components/Gallery';\nimport {\n IconChevronLeft,\n IconChevronRight,\n IconImage,\n IconVideoFill,\n} from '../../../../components/Icons';\nimport { GlobalModal } from '../../../../components/Modal';\nimport {\n SectionNavigatorHeader,\n type SectionNavigatorSectionContentProps,\n} from '../../SectionNavigator';\nimport { ChannelDetailListLoadingIndicator } from '../../ChannelDetailListLoadingIndicator';\nimport { getUserDisplayName } from '../ChannelMembersView/ChannelMembersView.utils';\nimport { ChannelMediaEmptyList } from './ChannelMediaEmptyList';\nimport type { ChannelMediaItem } from './ChannelMediaView.utils';\nimport { useChannelMediaSearch } from './useChannelMediaSearch';\nimport { Button } from '../../../../components';\n\n// Default items rendered per grid page (5 columns x 6 rows). Overridable via the\n// `itemsPerPage` prop. Intentionally decoupled from the search source's message\n// page size: a message carries a variable number of attachments, so message\n// pages and attachment pages don't align.\nconst DEFAULT_CHANNEL_MEDIA_ITEMS_PER_PAGE = 30;\n\ntype ChannelMediaGridItemProps = {\n BaseImage: React.ComponentType<BaseImageProps>;\n item: ChannelMediaItem;\n onClick: () => void;\n};\n\nconst ChannelMediaGridItem = ({\n BaseImage,\n item,\n onClick,\n}: ChannelMediaGridItemProps) => {\n const { t } = useTranslationContext('ChannelMediaView');\n const displayName = getUserDisplayName(item.user);\n const mediaSrc =\n item.type === 'video'\n ? item.galleryItem.videoThumbnailUrl\n : item.galleryItem.imageUrl;\n const durationLabel = formatTime(item.durationSeconds, 'floor');\n const label =\n item.type === 'video'\n ? t('aria/Open video shared by {{ name }}', { name: displayName })\n : t('aria/Open image shared by {{ name }}', { name: displayName });\n\n return (\n <button\n aria-label={label}\n className='str-chat__channel-detail__media-view__item'\n onClick={onClick}\n type='button'\n >\n {mediaSrc ? (\n <BaseImage\n alt={item.galleryItem.alt ?? item.galleryItem.title ?? ''}\n className='str-chat__channel-detail__media-view__item__media'\n src={mediaSrc}\n />\n ) : (\n <div\n aria-hidden='true'\n className='str-chat__channel-detail__media-view__item__placeholder'\n >\n <IconImage />\n </div>\n )}\n <Avatar\n aria-hidden='true'\n className='str-chat__channel-detail__media-view__item__avatar'\n imageUrl={item.user?.image}\n size='sm'\n userName={displayName}\n />\n {item.type === 'video' && (\n <Badge\n className='str-chat__channel-detail__media-view__item__duration'\n size='sm'\n variant='inverse'\n >\n <IconVideoFill className='str-chat__channel-detail__media-view__item__duration-icon' />\n {durationLabel ? <span>{durationLabel}</span> : null}\n </Badge>\n )}\n </button>\n );\n};\n\ntype ChannelMediaPaginationProps = {\n nextDisabled: boolean;\n onNext: () => void;\n onPrevious: () => void;\n previousDisabled: boolean;\n};\n\nconst ChannelMediaPagination = ({\n nextDisabled,\n onNext,\n onPrevious,\n previousDisabled,\n}: ChannelMediaPaginationProps) => {\n const { t } = useTranslationContext('ChannelMediaView');\n\n return (\n <div className='str-chat__channel-detail__media-view__pagination'>\n <Button\n appearance='outline'\n aria-label={t('aria/Previous page')}\n className='str-chat__channel-detail__media-view__pagination__button str-chat__channel-detail__media-view__pagination__button--previous'\n disabled={previousDisabled}\n onClick={onPrevious}\n size='md'\n variant='secondary'\n >\n <IconChevronLeft />\n {t('Previous')}\n </Button>\n <Button\n appearance='outline'\n aria-label={t('aria/Next page')}\n className='str-chat__channel-detail__media-view__pagination__button str-chat__channel-detail__media-view__pagination__button--next'\n disabled={nextDisabled}\n onClick={onNext}\n size='md'\n variant='secondary'\n >\n {t('Next')}\n <IconChevronRight />\n </Button>\n </div>\n );\n};\n\nexport type ChannelMediaViewProps = SectionNavigatorSectionContentProps & {\n /** Number of media items rendered per grid page. Defaults to 30. */\n itemsPerPage?: number;\n};\n\nexport const ChannelMediaView: React.ComponentType<ChannelMediaViewProps> = ({\n itemsPerPage = DEFAULT_CHANNEL_MEDIA_ITEMS_PER_PAGE,\n}) => {\n const { t } = useTranslationContext();\n const { close } = useModalContext();\n const {\n BaseImage = DefaultBaseImage,\n Gallery = DefaultGallery,\n Modal = GlobalModal,\n } = useComponentContext();\n const { channelMediaSearchSource, hasNext, hasResultsLoaded, isLoading, mediaItems } =\n useChannelMediaSearch();\n\n const [viewerOpen, setViewerOpen] = useState(false);\n const [selectedIndex, setSelectedIndex] = useState(0);\n const [page, setPage] = useState(0);\n const gridRef = useRef<HTMLDivElement>(null);\n // Set when \"Next\" reached a page that isn't loaded yet; the fill effect below\n // advances to it once the fetched attachments land, keeping fetches triggered\n // only by the button (or the initial mount load).\n const pendingNextRef = useRef(false);\n\n const galleryItems = useMemo(\n () => mediaItems.map((item) => item.galleryItem),\n [mediaItems],\n );\n\n const pageStart = page * itemsPerPage;\n const pageItems = useMemo(\n () => mediaItems.slice(pageStart, pageStart + itemsPerPage),\n [mediaItems, itemsPerPage, pageStart],\n );\n\n // More items already loaded beyond this page, or the source can fetch more.\n const canGoNext = mediaItems.length > pageStart + itemsPerPage || hasNext;\n const showPagination =\n mediaItems.length > itemsPerPage || (mediaItems.length > 0 && hasNext);\n\n const openViewer = useCallback((index: number) => {\n setSelectedIndex(index);\n setViewerOpen(true);\n }, []);\n\n const closeViewer = useCallback(() => {\n setViewerOpen(false);\n }, []);\n\n const goToPreviousPage = useCallback(() => {\n pendingNextRef.current = false;\n setPage((current) => Math.max(0, current - 1));\n }, []);\n\n const goToNextPage = useCallback(() => {\n const nextPageStart = (page + 1) * itemsPerPage;\n if (mediaItems.length > nextPageStart) {\n // The next page is already backed by loaded attachments — advance now.\n setPage(page + 1);\n } else if (hasNext) {\n // The next page isn't loaded yet. Request more and let the fill effect\n // advance once enough attachments arrive. Only a ref changes here (no\n // re-render), so the fetch fires exactly once per click.\n pendingNextRef.current = true;\n void channelMediaSearchSource.search();\n }\n }, [channelMediaSearchSource, hasNext, itemsPerPage, mediaItems.length, page]);\n\n // Forward-fill loop. Because a message yields a variable number of\n // attachments, one fetch may not fill a grid page (and the very first page\n // can arrive short). Keep pulling message pages until the visible page is\n // full or the channel is exhausted; nothing is ever discarded, so paging to\n // the end always reveals every attachment. Also resolves a pending \"Next\" by\n // advancing once its target page has data.\n useEffect(() => {\n if (isLoading) return;\n\n if (pendingNextRef.current) {\n const nextPageStart = (page + 1) * itemsPerPage;\n if (mediaItems.length > nextPageStart) {\n pendingNextRef.current = false;\n setPage((current) => current + 1);\n return;\n }\n if (!hasNext) {\n pendingNextRef.current = false;\n return;\n }\n void channelMediaSearchSource.search();\n return;\n }\n\n // Top up the visible page (covers the first page on mount).\n const need = pageStart + itemsPerPage;\n if (mediaItems.length < need && hasNext) {\n void channelMediaSearchSource.search();\n }\n }, [\n channelMediaSearchSource,\n hasNext,\n isLoading,\n itemsPerPage,\n mediaItems.length,\n page,\n pageStart,\n ]);\n\n // Each page replaces the previous one, so reset the grid scroll on change.\n useEffect(() => {\n const grid = gridRef.current;\n if (typeof grid?.scrollTo === 'function') {\n grid.scrollTo({ top: 0 });\n } else if (grid) {\n grid.scrollTop = 0;\n }\n }, [page]);\n\n return (\n <div className='str-chat__channel-detail__media-view'>\n <SectionNavigatorHeader close={close} title={t('Photos & videos')} />\n <Prompt.Body className='str-chat__channel-detail__media-view__body'>\n <div className='str-chat__channel-detail__media-view__grid' ref={gridRef}>\n <div className='str-chat__channel-detail__media-view__grid__content'>\n {pageItems.length > 0 ? (\n <div className='str-chat__channel-detail__media-view__grid__items'>\n {pageItems.map((item, index) => (\n <ChannelMediaGridItem\n BaseImage={BaseImage}\n item={item}\n key={item.id}\n onClick={() => openViewer(pageStart + index)}\n />\n ))}\n </div>\n ) : hasResultsLoaded ? (\n <ChannelMediaEmptyList />\n ) : null}\n <ChannelDetailListLoadingIndicator searchSource={channelMediaSearchSource} />\n {showPagination && (\n <ChannelMediaPagination\n nextDisabled={!canGoNext || isLoading}\n onNext={goToNextPage}\n onPrevious={goToPreviousPage}\n previousDisabled={page === 0}\n />\n )}\n </div>\n </div>\n </Prompt.Body>\n <Modal\n className={clsx(\n 'str-chat__gallery-modal',\n 'str-chat__channel-detail__media-view__viewer',\n )}\n onClose={closeViewer}\n open={viewerOpen}\n >\n <Gallery\n GalleryUI={GalleryUI}\n initialIndex={selectedIndex}\n items={galleryItems}\n onRequestClose={closeViewer}\n />\n </Modal>\n </div>\n );\n};\n","import type { Channel } from 'stream-chat';\nimport React, { useMemo, useState } from 'react';\n\nimport { useComponentContext, useTranslationContext } from '../../../../context';\nimport { Button } from '../../../../components/Button';\nimport {\n ContextMenu,\n ContextMenuButton,\n useDialogIsOpen,\n useDialogOnNearestManager,\n} from '../../../../components/Dialog';\nimport { useChannelDetailContext } from '../../ChannelDetailContext';\nimport { canUpdateChannelMembers } from './ChannelMembersView.utils';\nimport type {\n ChannelMembersHeaderActionsProps,\n ChannelMembersModeController,\n} from './ChannelMembersView';\nimport { IconUserAdd } from '../../../../components/Icons';\n\nexport type ChannelMembersHeaderActionType = 'addMembers' | (string & {});\n\nexport type ChannelMembersHeaderActionComponentProps = {\n closeMenu?: () => void;\n modeController: ChannelMembersModeController;\n};\n\n/** Where a header action renders: inline (`quick`) or inside the actions menu. */\nexport type ChannelMembersHeaderActionPlacement = 'quick' | 'menu';\n\nexport type ChannelMembersHeaderActionItem = {\n component: React.ComponentType<ChannelMembersHeaderActionComponentProps>;\n placement: ChannelMembersHeaderActionPlacement;\n type: ChannelMembersHeaderActionType;\n /**\n * Optional visibility gate for app-defined actions. Apps that add their own\n * actions are responsible for their permission checks here (the predicate\n * receives the `channel` so it can read `own_capabilities`). The SDK's own\n * actions are gated internally and do not rely on this.\n */\n filter?: (ctx: { channel: Channel }) => boolean;\n};\n\n/**\n * First-pass filter applied by {@link DefaultHeaderActions}. The SDK's own\n * actions are gated internally by capability — `addMembers` requires\n * `update-channel-members`; any other action is shown by default. App-defined\n * actions may further narrow visibility via their own `filter` predicate (which\n * is what an app should use to gate, e.g., a custom member-removal action).\n */\nexport const useBaseChannelMembersHeaderActionSetFilter = (\n channelMembersHeaderActionSet: ChannelMembersHeaderActionItem[],\n) => {\n const { channel } = useChannelDetailContext();\n const canManageChannelMembers = canUpdateChannelMembers(channel);\n\n return useMemo(\n () =>\n channelMembersHeaderActionSet.filter((action) => {\n const allowedByCapability =\n action.type !== 'addMembers' || canManageChannelMembers;\n\n return allowedByCapability && (action.filter?.({ channel }) ?? true);\n }),\n [canManageChannelMembers, channel, channelMembersHeaderActionSet],\n );\n};\n\nconst AddMembersHeaderAction = ({\n modeController,\n}: ChannelMembersHeaderActionComponentProps) => {\n const { t } = useTranslationContext();\n\n if (modeController.mode !== 'browse') return null;\n\n return (\n <Button\n appearance='outline'\n aria-label={t('Add channel members')}\n className='str-chat__channel-detail__channel-members-view__add-button'\n onClick={() => modeController.setMode('add')}\n size='md'\n variant='secondary'\n >\n {t('Add')}\n </Button>\n );\n};\n\nconst AddMembersMenuAction = ({\n closeMenu,\n modeController,\n}: ChannelMembersHeaderActionComponentProps) => {\n const { t } = useTranslationContext();\n\n if (modeController.mode !== 'browse') return null;\n\n return (\n <ContextMenuButton\n aria-label={t('Add channel members')}\n Icon={IconUserAdd}\n onClick={() => {\n modeController.setMode('add');\n closeMenu?.();\n }}\n >\n {t('Add')}\n </ContextMenuButton>\n );\n};\n\nexport const DefaultChannelMembersHeaderActions = {\n AddMembers: AddMembersHeaderAction,\n AddMembersMenu: AddMembersMenuAction,\n};\n\nexport const defaultChannelMembersHeaderActionSet: ChannelMembersHeaderActionItem[] = [\n {\n component: DefaultChannelMembersHeaderActions.AddMembers,\n placement: 'quick',\n type: 'addMembers',\n },\n];\n\nexport type ChannelMembersHeaderActionsMenuTriggerProps = {\n 'aria-expanded': boolean;\n onClick: () => void;\n referenceRef?: React.Ref<HTMLButtonElement>;\n};\n\nexport const DefaultHeaderActionsMenuTrigger = ({\n referenceRef,\n ...props\n}: ChannelMembersHeaderActionsMenuTriggerProps) => {\n const { t } = useTranslationContext();\n\n return (\n <Button\n appearance='outline'\n aria-label={t('Open members actions')}\n className='str-chat__channel-detail__channel-members-view__actions-button'\n ref={referenceRef}\n size='md'\n variant='secondary'\n {...props}\n >\n {t('Actions')}\n </Button>\n );\n};\n\nconst getHeaderActionsDialogId = (channelId?: string) =>\n `channel-members-header-actions-${channelId ?? 'unknown'}`;\n\nexport const DefaultHeaderActions = ({\n headerActionSet,\n HeaderActionsMenuTrigger = DefaultHeaderActionsMenuTrigger,\n modeController,\n}: ChannelMembersHeaderActionsProps) => {\n const { ContextMenu: ContextMenuComponent = ContextMenu } = useComponentContext();\n const { channel } = useChannelDetailContext();\n const actions = useBaseChannelMembersHeaderActionSetFilter(headerActionSet);\n const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(\n null,\n );\n const dialogId = getHeaderActionsDialogId(channel.id);\n const { dialog, dialogManager } = useDialogOnNearestManager({ id: dialogId });\n const dialogManagerId = dialogManager?.id;\n const dialogIsOpen = useDialogIsOpen(dialogId, dialogManagerId);\n\n if (!actions.length) return null;\n\n const quickActions = actions.filter((action) => action.placement === 'quick');\n const menuActions = actions.filter((action) => action.placement === 'menu');\n\n return (\n <div className='str-chat__channel-detail__channel-members-view__header-actions'>\n {quickActions.map(({ component: QuickComponent, type }) => (\n <QuickComponent key={type} modeController={modeController} />\n ))}\n\n {menuActions.length > 0 && (\n <>\n <HeaderActionsMenuTrigger\n aria-expanded={dialogIsOpen}\n onClick={() => {\n dialog.toggle();\n }}\n referenceRef={setReferenceElement}\n />\n <ContextMenuComponent\n aria-label='Members actions'\n className='str-chat__channel-detail__channel-members-view__header-actions-menu'\n dialogManagerId={dialogManagerId}\n id={dialog.id}\n onClose={() => dialog.close()}\n placement='bottom-start'\n referenceElement={referenceElement}\n tabIndex={-1}\n trapFocus\n >\n {menuActions.map(({ component: MenuComponent, type }) => (\n <MenuComponent\n closeMenu={() => dialog.close()}\n key={type}\n modeController={modeController}\n />\n ))}\n </ContextMenuComponent>\n </>\n )}\n </div>\n );\n};\n","import clsx from 'clsx';\nimport type { ComponentProps, ComponentType, ReactNode } from 'react';\nimport React, { forwardRef, useCallback, useMemo } from 'react';\nimport type { ComputeItemKey, VirtuosoProps } from 'react-virtuoso';\nimport { Virtuoso } from 'react-virtuoso';\n\n// Wraps the virtualized item list so views can attach padding/spacing to a\n// stable class instead of reaching into Virtuoso's internal markup.\nconst VirtualizedListContent = forwardRef<HTMLDivElement, ComponentProps<'div'>>(\n function VirtualizedListContent({ className, ...props }, ref) {\n return (\n <div\n {...props}\n className={clsx('str-chat__virtualized-list__content', className)}\n ref={ref}\n />\n );\n },\n);\n\nexport type VirtualizedListProps<T> = {\n /** Items to render. An empty array renders the `EmptyPlaceholder`. */\n data: T[];\n /** Renders a single item; do not add a React key, Virtuoso manages keys. */\n itemContent: (index: number, item: T) => ReactNode;\n 'aria-label'?: string;\n className?: string;\n computeItemKey?: ComputeItemKey<T, unknown>;\n /** Rendered in place of the list when `data` is empty. */\n EmptyPlaceholder?: ComponentType;\n /** Rendered below the items, e.g. a loading indicator for the next page. */\n Footer?: ComponentType;\n /** Called when the list is scrolled to the bottom to load the next page. */\n loadNext?: () => void;\n role?: string;\n /** Escape hatch for passing additional props straight to Virtuoso. */\n virtuosoProps?: VirtuosoProps<T, unknown>;\n};\n\n/**\n * Thin wrapper around `react-virtuoso`'s `Virtuoso` for the simple,\n * append-only, flat lists used across the ChannelDetail views. It keeps the\n * call sites declarative (data + itemContent + empty/footer slots) and hides\n * the infinite-scroll wiring.\n */\nexport const VirtualizedList = <T,>({\n className,\n computeItemKey,\n data,\n EmptyPlaceholder,\n Footer,\n itemContent,\n loadNext,\n virtuosoProps,\n ...rest\n}: VirtualizedListProps<T>) => {\n const atBottomStateChange = useCallback(\n (atBottom: boolean) => {\n if (atBottom) loadNext?.();\n },\n [loadNext],\n );\n\n const components = useMemo(\n () => ({\n EmptyPlaceholder,\n Footer,\n List: VirtualizedListContent,\n }),\n [EmptyPlaceholder, Footer],\n );\n\n return (\n <Virtuoso\n atBottomStateChange={atBottomStateChange}\n className={clsx('str-chat__virtualized-list', className)}\n components={components}\n computeItemKey={computeItemKey}\n data={data}\n itemContent={itemContent}\n {...rest}\n {...virtuosoProps}\n />\n );\n};\n","import { useEffect, useState } from 'react';\nimport type { Channel } from 'stream-chat';\n\nimport { getChannelMemberUserIds } from './ChannelMembersView.utils';\n\n// Channel events that add, remove or change a member. `channel.state.members` is\n// kept in sync by the SDK on these events, so re-reading the member ids on each\n// keeps the derived set reactive — no imperative bookkeeping from the views that\n// mutate membership.\nconst MEMBER_IDS_EVENTS = ['member.added', 'member.removed', 'member.updated'] as const;\n\n/** Reactive set of channel member user ids derived from real channel state. */\nexport const useChannelMemberIds = (channel: Channel) => {\n const [memberIds, setMemberIds] = useState(() => getChannelMemberUserIds(channel));\n\n useEffect(() => {\n const syncMemberIds = () => setMemberIds(getChannelMemberUserIds(channel));\n\n syncMemberIds();\n\n const subscriptions = MEMBER_IDS_EVENTS.map((event) =>\n channel.on(event, syncMemberIds),\n );\n\n return () => subscriptions.forEach((subscription) => subscription.unsubscribe());\n }, [channel]);\n\n return memberIds;\n};\n","import React, { useCallback, useEffect, useState } from 'react';\n\nimport { useTranslationContext } from '../../context';\nimport { TextInput } from '../../components/Form';\nimport { IconSearch } from '../../components/Icons';\n\nexport type ChannelDetailSearchInputProps = {\n autoFocus?: boolean;\n onSearchChange: (query: string) => void;\n resetKey?: number;\n};\n\nexport const ChannelDetailSearchInput = React.memo(\n ({ autoFocus, onSearchChange, resetKey }: ChannelDetailSearchInputProps) => {\n const { t } = useTranslationContext();\n const [searchInput, setSearchInput] = useState('');\n\n useEffect(() => {\n setSearchInput('');\n }, [resetKey]);\n\n const handleSearchChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n const { value } = event.target;\n setSearchInput(value);\n onSearchChange(value);\n },\n [onSearchChange],\n );\n\n return (\n <TextInput\n aria-label={t('Search')}\n autoComplete='off'\n autoFocus={autoFocus}\n className='str-chat__channel-detail__search-input'\n leading={<IconSearch />}\n onChange={handleSearchChange}\n placeholder={t('Search')}\n type='search'\n value={searchInput}\n />\n );\n },\n);\n\nChannelDetailSearchInput.displayName = 'ChannelDetailSearchInput';\n","import { IconSearch } from '../../components/Icons';\nimport type { PropsWithChildrenOnly } from '../../types/types';\n\nexport const ChannelDetailEmptyList = ({ children }: PropsWithChildrenOnly) => (\n <div className='str-chat__channel-detail__channel-members-view__empty-state'>\n <IconSearch />\n <div>{children}</div>\n </div>\n);\n","import { type SearchSourceState, type UserResponse, UserSearchSource } from 'stream-chat';\nimport React, { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { useChatContext, useTranslationContext } from '../../../../context';\nimport { useStateStore } from '../../../../store';\nimport { Avatar } from '../../../../components/Avatar';\nimport { Checkbox } from '../../../../components/Form';\nimport { IconMute } from '../../../../components/Icons';\nimport { ListItemLayout } from '../../../../components/ListItemLayout';\nimport { VirtualizedList } from '../../VirtualizedList';\nimport { Prompt } from '../../../../components/Dialog';\nimport { useChannelDetailContext } from '../../ChannelDetailContext';\nimport { canUpdateChannelMembers, getUserDisplayName } from './ChannelMembersView.utils';\nimport { useChannelMemberIds } from './useChannelMemberIds';\nimport type { ChannelMembersModeViewProps } from './ChannelMembersView';\nimport { useNotificationApi } from '../../../../components/Notifications';\nimport { ChannelDetailSearchInput } from '../../ChannelDetailSearchInput';\nimport { ChannelDetailEmptyList } from '../../ChannelDetailEmptyList';\nimport { ChannelDetailListLoadingIndicator } from '../../ChannelDetailListLoadingIndicator';\n\nexport type ChannelMembersAddViewProps = ChannelMembersModeViewProps & {\n searchSource?: UserSearchSource;\n};\n\nconst USER_SEARCH_PAGE_SIZE = 30;\n\nconst searchSourceItemsStateSelector = (state: SearchSourceState<UserResponse>) => ({\n isLoading: state.isLoading,\n users: state.items,\n});\n\nconst EMPTY_USERS: UserResponse[] = [];\n\nconst computeUserItemKey = (_: number, user: UserResponse) => user.id;\n\nconst MuteIndicator = () => (\n <IconMute className='str-chat__channel-detail__action-icon str-chat__channel-detail__action-icon--mute' />\n);\n\nconst readOnlyRootProps = {\n className: 'str-chat__channel-detail__channel-members-view__list-item',\n};\n\nconst ChannelMembersAddViewItem = ({\n canManageChannelMembers,\n isMember,\n isMuted,\n isSelected,\n toggleSelectedUser,\n user,\n}: {\n canManageChannelMembers: boolean;\n isMember: boolean;\n isMuted: boolean;\n isSelected: boolean;\n toggleSelectedUser: (userId: string) => void;\n user: UserResponse;\n}) => {\n const { t } = useTranslationContext();\n const displayName = getUserDisplayName(user);\n\n const LeadingSlot = useMemo(\n () =>\n function MemberAvatar() {\n return (\n <Avatar\n imageUrl={user.image}\n isOnline={user.online}\n size='md'\n userName={displayName}\n />\n );\n },\n [displayName, user.image, user.online],\n );\n\n const SelectableTrailingSlot = useMemo(\n () =>\n function SelectCheckbox() {\n return <Checkbox aria-hidden checked={isSelected} />;\n },\n [isSelected],\n );\n\n const selectableRootProps = useMemo(\n () => ({\n 'aria-pressed': isSelected,\n className: 'str-chat__channel-detail__channel-members-view__list-item',\n onClick: () => toggleSelectedUser(user.id),\n }),\n [isSelected, toggleSelectedUser, user.id],\n );\n\n // Only non-members can be selected for adding. Existing members are\n // listed (and flagged below) but render as a non-actionable row, like\n // the read-only no-permission case.\n if (canManageChannelMembers && !isMember) {\n return (\n <ListItemLayout\n LeadingSlot={LeadingSlot}\n RootElement='button'\n rootProps={selectableRootProps}\n title={displayName}\n TrailingSlot={SelectableTrailingSlot}\n />\n );\n }\n\n return (\n <ListItemLayout\n LeadingSlot={LeadingSlot}\n rootProps={readOnlyRootProps}\n subtitle={isMember ? t('Already a member') : undefined}\n title={displayName}\n TrailingSlot={isMuted ? MuteIndicator : undefined}\n />\n );\n};\n\nexport const ChannelMembersAddView = ({\n modeController,\n searchSource,\n}: ChannelMembersAddViewProps) => {\n const { client, mutes } = useChatContext();\n const { t } = useTranslationContext();\n const { channel } = useChannelDetailContext();\n const canManageChannelMembers = canUpdateChannelMembers(channel);\n const { addNotification } = useNotificationApi();\n\n const memberUserIds = useChannelMemberIds(channel);\n const memberIdSet = useMemo(() => new Set(memberUserIds), [memberUserIds]);\n\n const userSearchSource = useMemo(\n () =>\n searchSource ??\n new UserSearchSource(client, {\n allowEmptySearchString: true,\n pageSize: USER_SEARCH_PAGE_SIZE,\n resetOnNewSearchQuery: false,\n }),\n [client, searchSource],\n );\n\n const { isLoading, users } = useStateStore(\n userSearchSource.state,\n searchSourceItemsStateSelector,\n );\n\n const [isSaving, setIsSaving] = useState(false);\n const [selectedUserIds, setSelectedUserIds] = useState<string[]>([]);\n\n useEffect(() => {\n userSearchSource.activate();\n userSearchSource.search('');\n\n return () => userSearchSource.cancelScheduledQuery();\n }, [userSearchSource]);\n\n const selectedUserIdSet = useMemo(() => new Set(selectedUserIds), [selectedUserIds]);\n const mutedUserIdSet = useMemo(\n () => new Set(mutes.map((mute) => mute.target.id)),\n [mutes],\n );\n\n const handleSearchChange = useCallback(\n (query: string) => {\n userSearchSource.search(query);\n },\n [userSearchSource],\n );\n\n const toggleSelectedUser = useCallback(\n (userId: string) =>\n setSelectedUserIds((currentSelectedUserIds) =>\n currentSelectedUserIds.includes(userId)\n ? currentSelectedUserIds.filter((id) => id !== userId)\n : [...currentSelectedUserIds, userId],\n ),\n [],\n );\n\n const renderItem = useCallback(\n (_: number, user: UserResponse) => (\n <ChannelMembersAddViewItem\n canManageChannelMembers={canManageChannelMembers}\n isMember={memberIdSet.has(user.id)}\n isMuted={mutedUserIdSet.has(user.id)}\n isSelected={selectedUserIdSet.has(user.id)}\n toggleSelectedUser={toggleSelectedUser}\n user={user}\n />\n ),\n [\n canManageChannelMembers,\n memberIdSet,\n mutedUserIdSet,\n selectedUserIdSet,\n toggleSelectedUser,\n ],\n );\n\n // Only show the \"no results\" copy once a query has resolved (`users` is an\n // array); while the first page loads `users` is undefined and nothing shows.\n const EmptyPlaceholder = useMemo(\n () =>\n function ChannelMembersAddEmptyPlaceholder() {\n if (isLoading || !users) return null;\n return <ChannelDetailEmptyList>{t('No user found')}</ChannelDetailEmptyList>;\n },\n [isLoading, t, users],\n );\n\n const Footer = useMemo(\n () =>\n function ChannelMembersAddListFooter() {\n return <ChannelDetailListLoadingIndicator searchSource={userSearchSource} />;\n },\n [userSearchSource],\n );\n\n const handleSave = async () => {\n if (!canManageChannelMembers || !selectedUserIds.length || isSaving) return;\n\n setIsSaving(true);\n try {\n await channel.addMembers(selectedUserIds);\n addNotification({\n context: { channel },\n emitter: 'ChannelMembersView',\n message: t('{{ count }} members added', { count: selectedUserIds.length }),\n severity: 'success',\n type: 'api:channel:addMembers:success',\n });\n setSelectedUserIds([]);\n setIsSaving(false);\n modeController.setMode('browse');\n } catch (error) {\n setIsSaving(false);\n addNotification({\n context: { channel },\n emitter: 'ChannelMembersView',\n error: error as Error,\n message: t('Error adding members'),\n severity: 'error',\n type: 'api:channel:addMembers:failed',\n });\n }\n };\n\n return (\n <>\n <Prompt.Body className='str-chat__channel-members-view__body'>\n <ChannelDetailSearchInput autoFocus onSearchChange={handleSearchChange} />\n <VirtualizedList\n className='str-chat__channel-detail__channel-members-view__list'\n computeItemKey={computeUserItemKey}\n data={users ?? EMPTY_USERS}\n EmptyPlaceholder={EmptyPlaceholder}\n Footer={Footer}\n itemContent={renderItem}\n loadNext={userSearchSource.search}\n />\n </Prompt.Body>\n {canManageChannelMembers && selectedUserIds.length > 0 && (\n <Prompt.Footer>\n <Prompt.FooterControls>\n <Prompt.FooterControlsButtonPrimary disabled={isSaving} onClick={handleSave}>\n {t('Add {{ count }} members', { count: selectedUserIds.length })}\n </Prompt.FooterControlsButtonPrimary>\n </Prompt.FooterControls>\n </Prompt.Footer>\n )}\n </>\n );\n};\n","import { useEffect, useState } from 'react';\nimport type { Channel } from 'stream-chat';\n\n// Channel events that change (or may change) the member count. `channel.data` is\n// refreshed by the SDK on member add/remove and channel updates, so re-reading\n// `member_count` on these events keeps the value in sync with real state — no\n// imperative count bookkeeping from the views that mutate membership.\nconst MEMBER_COUNT_EVENTS = [\n 'member.added',\n 'member.removed',\n 'channel.updated',\n] as const;\n\n/** Reactive channel member count derived from real channel state. */\nexport const useChannelMemberCount = (channel: Channel) => {\n const [memberCount, setMemberCount] = useState(channel.data?.member_count ?? 0);\n\n useEffect(() => {\n const syncMemberCount = () => setMemberCount(channel.data?.member_count ?? 0);\n\n syncMemberCount();\n\n const subscriptions = MEMBER_COUNT_EVENTS.map((event) =>\n channel.on(event, syncMemberCount),\n );\n\n return () => subscriptions.forEach((subscription) => subscription.unsubscribe());\n }, [channel]);\n\n return memberCount;\n};\n","import {\n type ChannelMemberResponse,\n ChannelMemberSearchSource,\n type SearchSourceState,\n} from 'stream-chat';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { useStateStore } from '../../../../store';\nimport { useChannelDetailContext } from '../../ChannelDetailContext';\nimport { CHANNEL_MEMBERS_QUERY_LIMIT } from './ChannelMembersView.utils';\nimport { useChannelMemberCount } from './useChannelMemberCount';\n\nconst MEMBERS_SEARCH_DEBOUNCE_MS = 300;\n\nconst membersSearchSourceItemsStateSelector = (\n state: SearchSourceState<ChannelMemberResponse>,\n) => ({\n members: state.items,\n});\n\nexport const useChannelMembersSearch = () => {\n const { channel } = useChannelDetailContext();\n const fallbackMembers = useMemo(\n () => Object.values(channel.state?.members ?? {}),\n [channel],\n );\n // Skip activating/searching only when the server explicitly reports zero\n // members. `member_count` being undefined is treated as \"has members\" so we\n // never suppress loading on incomplete channel data. The count is tracked\n // reactively so a channel that gains its first member activates the list\n // without a remount.\n const memberCount = useChannelMemberCount(channel);\n const hasMembers = channel.data?.member_count === undefined || memberCount !== 0;\n const membersSearchSource = useMemo(\n () =>\n new ChannelMemberSearchSource(channel, {\n allowEmptySearchString: true,\n debounceMs: MEMBERS_SEARCH_DEBOUNCE_MS,\n pageSize: CHANNEL_MEMBERS_QUERY_LIMIT,\n resetOnNewSearchQuery: false,\n }),\n [channel],\n );\n const { members } = useStateStore(\n membersSearchSource.state,\n membersSearchSourceItemsStateSelector,\n );\n const [searchInputResetKey, setSearchInputResetKey] = useState(0);\n\n const resetMembersSearch = useCallback(() => {\n membersSearchSource.cancelScheduledQuery();\n setSearchInputResetKey((currentResetKey) => currentResetKey + 1);\n membersSearchSource.resetState();\n membersSearchSource.activate();\n void membersSearchSource.search('');\n }, [membersSearchSource]);\n\n const handleSearchChange = useCallback(\n (query: string) => {\n membersSearchSource.search(query.trim());\n },\n [membersSearchSource],\n );\n\n useEffect(() => {\n if (!hasMembers) return;\n membersSearchSource.activate();\n void membersSearchSource.search('');\n }, [hasMembers, membersSearchSource]);\n\n useEffect(\n () => () => {\n membersSearchSource.cancelScheduledQuery();\n },\n [membersSearchSource],\n );\n\n return {\n displayedMembers: members ?? fallbackMembers,\n handleSearchChange,\n hasMembers,\n membersSearchSource,\n resetMembersSearch,\n searchInputResetKey,\n };\n};\n","import type { ChannelMemberResponse } from 'stream-chat';\nimport React, { useCallback, useMemo } from 'react';\n\nimport { useChatContext, useTranslationContext } from '../../../../context';\nimport { Avatar } from '../../../../components/Avatar';\nimport { IconMute } from '../../../../components/Icons';\nimport { ListItemLayout } from '../../../../components/ListItemLayout';\nimport { VirtualizedList } from '../../VirtualizedList';\nimport { Prompt } from '../../../../components/Dialog';\nimport {\n getMemberDisplayName,\n getMemberUserId,\n getUserDisplayName,\n} from './ChannelMembersView.utils';\nimport { ChannelDetailEmptyList } from '../../ChannelDetailEmptyList';\nimport { ChannelDetailListLoadingIndicator } from '../../ChannelDetailListLoadingIndicator';\nimport { ChannelDetailSearchInput } from '../../ChannelDetailSearchInput';\nimport { useChannelMembersSearch } from './useChannelMembersSearch';\n\nconst getMemberRoleTranslation = (\n member: ChannelMemberResponse,\n t: ReturnType<typeof useTranslationContext>['t'],\n) => {\n if ([member.user?.role, member.channel_role].includes('admin')) return t('Admin');\n if (member.channel_role === 'channel_moderator' || member.channel_role === 'moderator')\n return t('Moderator');\n if (member.role === 'owner') return t('Owner');\n\n return undefined;\n};\n\nconst getPresenceStatusText = (\n user: ChannelMemberResponse['user'],\n t: ReturnType<typeof useTranslationContext>['t'],\n) => {\n if (user?.online) return t('Online');\n\n if (user?.last_active) {\n return t('Last seen {{ timestamp }}', {\n timestamp: t('timestamp/ChannelMembersLastActive', {\n timestamp: user.last_active,\n }),\n });\n }\n\n return t('Offline');\n};\n\nconst ChannelMembersBrowseViewItem = ({\n isMuted,\n member,\n onMemberSelect,\n}: {\n isMuted: boolean;\n member: ChannelMemberResponse;\n onMemberSelect?: (member: ChannelMemberResponse) => void;\n}) => {\n const { t } = useTranslationContext();\n const user = member.user;\n const displayName = getMemberDisplayName(member);\n const roleTranslation = getMemberRoleTranslation(member, t);\n\n const LeadingSlot = useMemo(\n () =>\n function MemberAvatar() {\n return (\n <Avatar\n imageUrl={user?.image}\n isOnline={user?.online}\n size='md'\n userName={getUserDisplayName(user)}\n />\n );\n },\n [user],\n );\n\n const TrailingSlot = useMemo(\n () =>\n function MemberTrailingSlot() {\n return (\n <div className='str-chat__channel-detail__channel-members-view__list-item__trailing-slot'>\n {roleTranslation ? (\n <span className='str-chat__channel-detail__channel-members-view__role-label'>\n {roleTranslation}\n </span>\n ) : null}\n {isMuted ? (\n <IconMute className='str-chat__channel-detail__channel-members-view__list-item__indicator-icon str-chat__channel-detail__channel-members-view__list-item__indicator-icon--mute' />\n ) : null}\n </div>\n );\n },\n [isMuted, roleTranslation],\n );\n\n const rootProps = useMemo(\n () => ({\n 'aria-label': t('View member details for {{ member }}', {\n member: displayName,\n }),\n className: 'str-chat__channel-detail__channel-members-view__list-item',\n onClick: () => onMemberSelect?.(member),\n }),\n [displayName, member, onMemberSelect, t],\n );\n\n return (\n <ListItemLayout\n LeadingSlot={LeadingSlot}\n RootElement='button'\n rootProps={rootProps}\n subtitle={getPresenceStatusText(user, t)}\n title={displayName}\n TrailingSlot={TrailingSlot}\n />\n );\n};\n\nconst computeMemberItemKey = (_: number, member: ChannelMemberResponse) =>\n getMemberUserId(member) as string;\n\nexport type ChannelMembersBrowseViewProps = {\n onMemberSelect?: (member: ChannelMemberResponse) => void;\n};\n\nexport const ChannelMembersBrowseView = ({\n onMemberSelect,\n}: ChannelMembersBrowseViewProps) => {\n const { mutes } = useChatContext();\n const { t } = useTranslationContext();\n const {\n displayedMembers,\n handleSearchChange,\n hasMembers,\n membersSearchSource,\n searchInputResetKey,\n } = useChannelMembersSearch();\n const mutedUserIdSet = useMemo(\n () => new Set(mutes.map((mute) => mute.target.id)),\n [mutes],\n );\n\n // Only members with a resolvable user id are rendered; pre-filtering keeps the\n // virtualized item renderer total in sync with what it can actually display.\n const renderableMembers = useMemo(\n () => displayedMembers.filter((member) => getMemberUserId(member)),\n [displayedMembers],\n );\n\n const renderItem = useCallback(\n (_: number, member: ChannelMemberResponse) => (\n <ChannelMembersBrowseViewItem\n isMuted={mutedUserIdSet.has(getMemberUserId(member) as string)}\n member={member}\n onMemberSelect={onMemberSelect}\n />\n ),\n [mutedUserIdSet, onMemberSelect],\n );\n\n const EmptyPlaceholder = useMemo(\n () =>\n function ChannelMembersEmptyPlaceholder() {\n return <ChannelDetailEmptyList>{t('No member found')}</ChannelDetailEmptyList>;\n },\n [t],\n );\n\n const Footer = useMemo(\n () =>\n function ChannelMembersListFooter() {\n return <ChannelDetailListLoadingIndicator searchSource={membersSearchSource} />;\n },\n [membersSearchSource],\n );\n\n return (\n <Prompt.Body className='str-chat__channel-members-view__body'>\n {hasMembers && (\n <ChannelDetailSearchInput\n onSearchChange={handleSearchChange}\n resetKey={searchInputResetKey}\n />\n )}\n <VirtualizedList\n className='str-chat__channel-detail__channel-members-view__list'\n computeItemKey={computeMemberItemKey}\n data={renderableMembers}\n EmptyPlaceholder={EmptyPlaceholder}\n Footer={Footer}\n itemContent={renderItem}\n loadNext={hasMembers ? membersSearchSource.search : undefined}\n />\n </Prompt.Body>\n );\n};\n","import clsx from 'clsx';\nimport debounce from 'lodash.debounce';\nimport uniqBy from 'lodash.uniqby';\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport type { ChannelMemberResponse } from 'stream-chat';\n\nimport {\n useChannelListContext,\n useChatContext,\n useComponentContext,\n useModalContext,\n useTranslationContext,\n} from '../../../../context';\nimport { useStableCallback } from '../../../../utils';\nimport { useStateStore } from '../../../../store';\nimport { Alert } from '../../../../components/Dialog';\nimport { Button } from '../../../../components/Button';\nimport { Switch } from '../../../../components/Form';\nimport {\n IconAudio,\n IconMessageBubble,\n IconMute,\n IconNoSign,\n IconUserRemove,\n} from '../../../../components/Icons';\nimport { ListItemLayout } from '../../../../components/ListItemLayout';\nimport { GlobalModal } from '../../../../components/Modal';\nimport { useNotificationApi } from '../../../../components/Notifications';\nimport { useChannelDetailContext } from '../../ChannelDetailContext';\n\nexport type ChannelMemberActionType =\n | 'blockUser'\n | 'muteUser'\n | 'removeUser'\n | 'sendMessage'\n | (string & {});\n\nexport type ChannelMemberActionItem = {\n Component: React.ComponentType;\n type: ChannelMemberActionType;\n};\n\ntype ChannelMemberActionContextValue = {\n member: ChannelMemberResponse;\n memberDisplayName: string;\n targetUserId?: string;\n};\n\nconst ChannelMemberActionContext = createContext<\n ChannelMemberActionContextValue | undefined\n>(undefined);\n\nexport const ChannelMemberActionProvider = ({\n children,\n value,\n}: React.PropsWithChildren<{ value: ChannelMemberActionContextValue }>) => (\n <ChannelMemberActionContext.Provider value={value}>\n {children}\n </ChannelMemberActionContext.Provider>\n);\n\nexport const useChannelMemberActionContext = () => {\n const contextValue = useContext(ChannelMemberActionContext);\n if (!contextValue) {\n throw new Error(\n 'The useChannelMemberActionContext hook was called outside of ChannelMemberActionProvider.',\n );\n }\n\n return contextValue;\n};\n\nconst toError = (error: unknown) =>\n error instanceof Error ? error : new Error('An unknown error occurred');\n\nconst MemberMuteActionIcon = () => (\n <IconMute className='str-chat__channel-detail__action-icon str-chat__channel-detail__action-icon--mute' />\n);\n\nconst MemberUnmuteActionIcon = () => (\n <IconAudio className='str-chat__channel-detail__action-icon str-chat__channel-detail__action-icon--unmute' />\n);\n\nconst SendDirectMessageActionIcon = () => (\n <IconMessageBubble className='str-chat__channel-detail__action-icon' />\n);\n\nconst BlockUserActionIcon = () => (\n <IconNoSign className='str-chat__icon--destructive str-chat__channel-detail__action-icon str-chat__channel-detail__action-icon--block-user' />\n);\n\nconst RemoveUserActionIcon = () => (\n <IconUserRemove className='str-chat__icon--destructive str-chat__channel-detail__action-icon str-chat__channel-detail__action-icon--remove-user' />\n);\n\nconst channelMemberDetailActionClassName = 'str-chat__channel-member-detail-action';\n\nconst blockedUsersSelector = ({ userIds }: { userIds: string[] }) => ({ userIds });\n\ntype ChannelMemberConfirmationAlertProps = {\n action: 'blockUser' | 'removeUser';\n cancelLabel: string;\n confirmLabel: string;\n description: string;\n isSubmitting?: boolean;\n onCancel: () => void;\n onConfirm: () => void;\n testId: string;\n title: string;\n};\n\nconst ChannelMemberConfirmationAlert = ({\n action,\n cancelLabel,\n confirmLabel,\n description,\n isSubmitting,\n onCancel,\n onConfirm,\n testId,\n title,\n}: ChannelMemberConfirmationAlertProps) => (\n <Alert.Root\n className={clsx('str-chat__channel-member-confirmation-alert', {\n [`str-chat__channel-member-confirmation-alert--${action}`]: action,\n })}\n data-testid={testId}\n >\n <Alert.Header description={description} title={title} />\n <Alert.Actions>\n <Button\n appearance='solid'\n data-testid={`${testId}-confirm-button`}\n disabled={isSubmitting}\n onClick={onConfirm}\n size='md'\n variant='danger'\n >\n {confirmLabel}\n </Button>\n <Button\n appearance='outline'\n autoFocus\n data-testid={`${testId}-cancel-button`}\n disabled={isSubmitting}\n onClick={onCancel}\n size='md'\n variant='secondary'\n >\n {cancelLabel}\n </Button>\n </Alert.Actions>\n </Alert.Root>\n);\n\nconst useChannelMemberActionFilterState = () => {\n const { client } = useChatContext();\n const { channel } = useChannelDetailContext();\n const { targetUserId } = useChannelMemberActionContext();\n const ownCapabilities = channel.data?.own_capabilities;\n const isCurrentUser = targetUserId === client.user?.id;\n\n return {\n // Blocking is a personal, per-user action (client.blockUser/unBlockUser),\n // independent of channel moderation capabilities like 'ban-channel-members'.\n canBlockUser: !isCurrentUser && !!targetUserId,\n canMuteUser: !isCurrentUser && !!targetUserId,\n canRemoveUser:\n !isCurrentUser &&\n !!targetUserId &&\n ownCapabilities?.includes('update-channel-members'),\n canSendMessage: !isCurrentUser && !!targetUserId,\n };\n};\n\nexport const useBaseChannelMemberActionSetFilter = (\n channelMemberActionSet: ChannelMemberActionItem[],\n) => {\n const { canBlockUser, canMuteUser, canRemoveUser, canSendMessage } =\n useChannelMemberActionFilterState();\n\n return useMemo(\n () =>\n channelMemberActionSet.filter((action) => {\n switch (action.type) {\n case 'blockUser':\n return canBlockUser;\n case 'muteUser':\n return canMuteUser;\n case 'removeUser':\n return canRemoveUser;\n case 'sendMessage':\n return canSendMessage;\n default:\n return true;\n }\n }),\n [canBlockUser, canMuteUser, canRemoveUser, canSendMessage, channelMemberActionSet],\n );\n};\n\nconst SendDirectMessageAction = () => {\n const { client, setActiveChannel } = useChatContext();\n const { setChannels } = useChannelListContext();\n const { close } = useModalContext();\n const { channel } = useChannelDetailContext();\n const { addNotification } = useNotificationApi();\n const { t } = useTranslationContext();\n const { targetUserId } = useChannelMemberActionContext();\n const [isSending, setIsSending] = useState(false);\n\n const openDirectMessage = useCallback(async () => {\n if (!client.userID || !targetUserId || isSending) return;\n\n setIsSending(true);\n try {\n const directMessageChannel = client.channel(channel.type, {\n members: [client.userID, targetUserId],\n });\n await directMessageChannel.watch();\n setActiveChannel(directMessageChannel);\n setChannels?.((channels) => uniqBy([directMessageChannel, ...channels], 'cid'));\n close();\n } catch (error) {\n addNotification({\n context: { channel },\n emitter: 'ChannelMemberDetail',\n error: toError(error),\n message: t('Error opening direct message'),\n severity: 'error',\n type: 'api:channel:watch:failed',\n });\n } finally {\n setIsSending(false);\n }\n }, [\n addNotification,\n channel,\n client,\n close,\n isSending,\n setActiveChannel,\n setChannels,\n t,\n targetUserId,\n ]);\n\n const rootProps = useMemo(\n () => ({\n className: channelMemberDetailActionClassName,\n disabled: isSending,\n onClick: openDirectMessage,\n }),\n [isSending, openDirectMessage],\n );\n\n return (\n <ListItemLayout\n LeadingIcon={SendDirectMessageActionIcon}\n RootElement='button'\n rootProps={rootProps}\n title={t('Send direct message')}\n />\n );\n};\n\nconst UserMuteAction = () => {\n const { channel } = useChannelDetailContext();\n const { client, mutes } = useChatContext();\n const { addNotification } = useNotificationApi();\n const { t } = useTranslationContext();\n const { targetUserId } = useChannelMemberActionContext();\n const userMuted =\n !!targetUserId && mutes.some((mute) => mute.target.id === targetUserId);\n const [optimisticUserMuted, setOptimisticUserMuted] = useState(userMuted);\n\n useEffect(() => {\n setOptimisticUserMuted(userMuted);\n }, [userMuted]);\n\n const toggleUserMuteRequest = useStableCallback(\n (nextMuted: boolean, userId?: string) => {\n if (!userId) return;\n\n if (!nextMuted) {\n return client\n .unmuteUser(userId)\n .then(() =>\n addNotification({\n context: { channel },\n emitter: 'ChannelMemberDetail',\n message: t('User unmuted'),\n severity: 'success',\n type: 'api:user:unmute:success',\n }),\n )\n .catch((error) => {\n // Reconcile to the truth source rather than a hard-coded value: with\n // the debounced request, optimistic state may have flipped multiple\n // times, so a fixed boolean can land on the wrong state.\n setOptimisticUserMuted(userMuted);\n return addNotification({\n context: { channel },\n emitter: 'ChannelMemberDetail',\n error: toError(error),\n message: t('Error unmuting user'),\n severity: 'error',\n type: 'api:user:unmute:failed',\n });\n });\n }\n\n return client\n .muteUser(userId)\n .then(() =>\n addNotification({\n context: { channel },\n emitter: 'ChannelMemberDetail',\n message: t('User muted'),\n severity: 'success',\n type: 'api:user:mute:success',\n }),\n )\n .catch((error) => {\n setOptimisticUserMuted(userMuted);\n return addNotification({\n context: { channel },\n emitter: 'ChannelMemberDetail',\n error: toError(error),\n message: t('Error muting user'),\n severity: 'error',\n type: 'api:user:mute:failed',\n });\n });\n },\n );\n\n const toggleUserMute = useMemo(\n () => debounce(toggleUserMuteRequest, 1000),\n [toggleUserMuteRequest],\n );\n\n useEffect(\n () => () => {\n toggleUserMute.cancel();\n },\n [toggleUserMute],\n );\n\n const toggleOptimisticUserMute = useCallback(() => {\n const nextMuted = !optimisticUserMuted;\n setOptimisticUserMuted(nextMuted);\n toggleUserMute(nextMuted, targetUserId);\n }, [optimisticUserMuted, targetUserId, toggleUserMute]);\n\n const rootProps = useMemo(\n () => ({\n 'aria-pressed': optimisticUserMuted,\n className: clsx('str-chat__form__switch-field', channelMemberDetailActionClassName),\n onClick: toggleOptimisticUserMute,\n }),\n [optimisticUserMuted, toggleOptimisticUserMute],\n );\n const TrailingSlot = useMemo(() => {\n function UserMuteSwitch() {\n return <Switch on={optimisticUserMuted} presentation />;\n }\n\n return UserMuteSwitch;\n }, [optimisticUserMuted]);\n\n return (\n <ListItemLayout\n LeadingIcon={optimisticUserMuted ? MemberUnmuteActionIcon : MemberMuteActionIcon}\n RootElement='button'\n rootProps={rootProps}\n title={optimisticUserMuted ? t('Unmute user') : t('Mute user')}\n TrailingSlot={TrailingSlot}\n />\n );\n};\n\nconst BlockUserAction = () => {\n const { client } = useChatContext();\n const { Modal = GlobalModal } = useComponentContext();\n const { channel } = useChannelDetailContext();\n const { addNotification } = useNotificationApi();\n const { t } = useTranslationContext();\n const { memberDisplayName, targetUserId } = useChannelMemberActionContext();\n const { userIds: blockedUserIds } = useStateStore(\n client.blockedUsers,\n blockedUsersSelector,\n );\n const isBlocked = !!targetUserId && new Set(blockedUserIds).has(targetUserId);\n const [alertOpen, setAlertOpen] = useState(false);\n const [userBlockInProgress, setUserBlockInProgress] = useState(false);\n\n const closeBlockUserAlert = useCallback(() => {\n setAlertOpen(false);\n }, []);\n\n const openBlockUserAlert = useCallback(() => {\n setAlertOpen(true);\n }, []);\n\n const unblockUser = useCallback(async () => {\n if (!targetUserId) return;\n\n try {\n setUserBlockInProgress(true);\n await client.unBlockUser(targetUserId);\n addNotification({\n context: { channel },\n emitter: 'ChannelMemberDetail',\n message: t('User unblocked'),\n severity: 'success',\n type: 'api:user:unblock:success',\n });\n } catch (error) {\n addNotification({\n context: { channel },\n emitter: 'ChannelMemberDetail',\n error: toError(error),\n message: t('Error unblocking user'),\n severity: 'error',\n type: 'api:user:unblock:failed',\n });\n } finally {\n setAlertOpen(false);\n setUserBlockInProgress(false);\n }\n }, [addNotification, channel, client, t, targetUserId]);\n\n const blockUser = useCallback(async () => {\n if (!targetUserId) return;\n\n try {\n setUserBlockInProgress(true);\n await client.blockUser(targetUserId);\n addNotification({\n context: { channel },\n emitter: 'ChannelMemberDetail',\n message: t('User blocked'),\n severity: 'success',\n type: 'api:user:block:success',\n });\n } catch (error) {\n addNotification({\n context: { channel },\n emitter: 'ChannelMemberDetail',\n error: toError(error),\n message: t('Error blocking user'),\n severity: 'error',\n type: 'api:user:block:failed',\n });\n } finally {\n setAlertOpen(false);\n setUserBlockInProgress(false);\n }\n }, [addNotification, channel, client, t, targetUserId]);\n\n const rootProps = useMemo(\n () => ({\n className: channelMemberDetailActionClassName,\n disabled: userBlockInProgress,\n onClick: openBlockUserAlert,\n }),\n [openBlockUserAlert, userBlockInProgress],\n );\n\n return (\n <>\n <ListItemLayout\n destructive\n LeadingIcon={BlockUserActionIcon}\n RootElement='button'\n rootProps={rootProps}\n title={isBlocked ? t('Unblock user') : t('Block user')}\n />\n <Modal open={alertOpen} role='alertdialog'>\n <ChannelMemberConfirmationAlert\n action='blockUser'\n cancelLabel={t('Cancel')}\n confirmLabel={isBlocked ? t('Unblock user') : t('Block user')}\n description={\n isBlocked\n ? t('{{ member }} will be able to message you again.', {\n member: memberDisplayName,\n })\n : t(\"{{ member }} won't be able to message you anymore.\", {\n member: memberDisplayName,\n })\n }\n isSubmitting={userBlockInProgress}\n onCancel={closeBlockUserAlert}\n onConfirm={isBlocked ? unblockUser : blockUser}\n testId='channel-detail-block-member-alert'\n title={isBlocked ? t('Unblock user') : t('Block user')}\n />\n </Modal>\n </>\n );\n};\n\nconst RemoveUserAction = () => {\n const { Modal = GlobalModal } = useComponentContext();\n const { channel } = useChannelDetailContext();\n const { addNotification } = useNotificationApi();\n const { t } = useTranslationContext();\n const { memberDisplayName, targetUserId } = useChannelMemberActionContext();\n const [alertOpen, setAlertOpen] = useState(false);\n const [removeMemberInProgress, setRemoveMemberInProgress] = useState(false);\n\n const closeRemoveUserAlert = useCallback(() => {\n setAlertOpen(false);\n }, []);\n\n const openRemoveUserAlert = useCallback(() => {\n setAlertOpen(true);\n }, []);\n\n const removeUser = useCallback(async () => {\n if (!targetUserId) return;\n\n try {\n setRemoveMemberInProgress(true);\n await channel.removeMembers([targetUserId]);\n addNotification({\n context: { channel },\n emitter: 'ChannelMemberDetail',\n message: t('User removed'),\n severity: 'success',\n type: 'api:channel:remove-members:success',\n });\n setAlertOpen(false);\n } catch (error) {\n addNotification({\n context: { channel },\n emitter: 'ChannelMemberDetail',\n error: toError(error),\n message: t('Error removing user'),\n severity: 'error',\n type: 'api:channel:remove-members:failed',\n });\n } finally {\n setRemoveMemberInProgress(false);\n }\n }, [addNotification, channel, t, targetUserId]);\n\n const rootProps = useMemo(\n () => ({\n className: channelMemberDetailActionClassName,\n disabled: removeMemberInProgress,\n onClick: openRemoveUserAlert,\n }),\n [openRemoveUserAlert, removeMemberInProgress],\n );\n\n return (\n <>\n <ListItemLayout\n destructive\n LeadingIcon={RemoveUserActionIcon}\n RootElement='button'\n rootProps={rootProps}\n title={t('Remove user')}\n />\n <Modal open={alertOpen} role='alertdialog'>\n <ChannelMemberConfirmationAlert\n action='removeUser'\n cancelLabel={t('Cancel')}\n confirmLabel={t('Remove user')}\n description={t('Remove {{ member }} from this channel?', {\n member: memberDisplayName,\n })}\n isSubmitting={removeMemberInProgress}\n onCancel={closeRemoveUserAlert}\n onConfirm={removeUser}\n testId='channel-detail-remove-member-alert'\n title={t('Remove user')}\n />\n </Modal>\n </>\n );\n};\n\nexport const DefaultChannelMemberActions = {\n BlockUser: BlockUserAction,\n MuteUser: UserMuteAction,\n RemoveUser: RemoveUserAction,\n SendDirectMessage: SendDirectMessageAction,\n};\n\nexport const defaultChannelMemberActionSet: ChannelMemberActionItem[] = [\n {\n Component: DefaultChannelMemberActions.SendDirectMessage,\n type: 'sendMessage',\n },\n {\n Component: DefaultChannelMemberActions.MuteUser,\n type: 'muteUser',\n },\n {\n Component: DefaultChannelMemberActions.BlockUser,\n type: 'blockUser',\n },\n {\n Component: DefaultChannelMemberActions.RemoveUser,\n type: 'removeUser',\n },\n];\n","import React, { useMemo } from 'react';\nimport type { ChannelMemberResponse } from 'stream-chat';\n\nimport {\n useComponentContext,\n useModalContext,\n useTranslationContext,\n} from '../../../../context';\nimport {\n SectionNavigatorHeader,\n type SectionNavigatorSectionContentProps,\n} from '../../SectionNavigator';\nimport { ChannelAvatar as DefaultChannelAvatar } from '../../../../components/Avatar';\nimport { Prompt } from '../../../../components/Dialog';\nimport {\n type ChannelMemberActionItem,\n ChannelMemberActionProvider,\n defaultChannelMemberActionSet,\n useBaseChannelMemberActionSetFilter,\n useChannelMemberActionContext,\n} from './ChannelMemberActions.defaults';\nimport { getMemberDisplayName } from '../ChannelMembersView/ChannelMembersView.utils';\n\nexport type ChannelMemberDetailProps = SectionNavigatorSectionContentProps & {\n /** The member whose details are shown. Required — the view is always opened\n * for a specific, selected member. */\n member: ChannelMemberResponse;\n channelMemberActionSet?: ChannelMemberActionItem[];\n onBack?: () => void;\n};\n\nconst getPresenceStatusText = (\n user: ChannelMemberResponse['user'],\n t: ReturnType<typeof useTranslationContext>['t'],\n) => {\n if (user?.online) return t('Online');\n\n if (user?.last_active) {\n return t('Last seen {{ timestamp }}', {\n timestamp: t('timestamp/ChannelMembersLastActive', {\n timestamp: user.last_active,\n }),\n });\n }\n\n return t('Offline');\n};\n\nexport const ChannelMemberDetail = ({\n channelMemberActionSet = defaultChannelMemberActionSet,\n member,\n onBack,\n}: ChannelMemberDetailProps) => {\n const { t } = useTranslationContext();\n\n const memberDisplayName = getMemberDisplayName(member);\n const memberStatusText = getPresenceStatusText(member.user, t);\n\n const actionContextValue = useMemo(\n () => ({\n member,\n memberDisplayName,\n targetUserId: member.user?.id || member.user_id,\n }),\n [member, memberDisplayName],\n );\n\n return (\n <ChannelMemberActionProvider value={actionContextValue}>\n <ChannelMemberDetailContent\n channelMemberActionSet={channelMemberActionSet}\n memberDisplayName={memberDisplayName}\n memberStatusText={memberStatusText}\n onBack={onBack}\n />\n </ChannelMemberActionProvider>\n );\n};\n\ntype ChannelMemberDetailContentProps = {\n channelMemberActionSet: ChannelMemberActionItem[];\n memberDisplayName: string;\n memberStatusText: string;\n onBack?: () => void;\n};\n\nconst ChannelMemberDetailContent = ({\n channelMemberActionSet,\n memberDisplayName,\n memberStatusText,\n onBack,\n}: ChannelMemberDetailContentProps) => {\n const { close } = useModalContext();\n const { t } = useTranslationContext();\n const { Avatar = DefaultChannelAvatar } = useComponentContext();\n const { member } = useChannelMemberActionContext();\n\n const filteredActions = useBaseChannelMemberActionSetFilter(channelMemberActionSet);\n\n return (\n <div className='str-chat__channel-detail__channel-member-detail-view'>\n <SectionNavigatorHeader close={close} goBack={onBack} title={t('Member detail')} />\n <Prompt.Body className='str-chat__channel-detail__channel-member-detail-view__body'>\n <div className='str-chat__channel-detail__channel-member-detail-view__profile'>\n <Avatar\n imageUrl={member.user?.image}\n isOnline={member.user?.online}\n size='2xl'\n userName={memberDisplayName}\n />\n <div className='str-chat__channel-detail__channel-member-detail-view__profile__details'>\n <div className='str-chat__channel-detail__channel-member-detail-view__profile__details__title'>\n {memberDisplayName}\n </div>\n <div className='str-chat__channel-detail__channel-member-detail-view__profile__details__connection-status'>\n {memberStatusText}\n </div>\n </div>\n </div>\n\n <div className='str-chat__channel-detail__channel-member-detail-view__actions str-chat__form__switch-fieldset'>\n {filteredActions.map(({ Component, type }) => (\n <Component key={type} />\n ))}\n </div>\n </Prompt.Body>\n </div>\n );\n};\n","import React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport type { ChannelMemberResponse } from 'stream-chat';\n\nimport { useModalContext, useTranslationContext } from '../../../../context';\nimport { useChannelDetailContext } from '../../ChannelDetailContext';\nimport { ChannelMemberDetail } from '../ChannelMemberDetailView';\nimport {\n type ChannelMembersHeaderActionItem,\n type ChannelMembersHeaderActionsMenuTriggerProps,\n defaultChannelMembersHeaderActionSet,\n DefaultHeaderActions,\n} from './ChannelMembersHeaderActions.defaults';\nimport { ChannelMembersAddView } from './ChannelMembersAddView';\nimport { ChannelMembersBrowseView } from './ChannelMembersBrowseView';\nimport { useChannelMemberCount } from './useChannelMemberCount';\nimport {\n SectionNavigatorHeader,\n type SectionNavigatorSectionContentProps,\n} from '../../SectionNavigator';\n\nexport type ChannelMembersHeaderActionsProps = {\n modeController: ChannelMembersModeController;\n HeaderActionsMenuTrigger?: React.ComponentType<ChannelMembersHeaderActionsMenuTriggerProps>;\n headerActionSet: ChannelMembersHeaderActionItem[];\n};\n\n/**\n * Built-in modes are rendered by `ChannelMembersView` itself. Any other string\n * is treated as a custom mode and rendered from the injected `modeViews` registry.\n */\nexport type ChannelMembersViewMode = 'add' | 'browse' | 'memberDetail' | (string & {});\n\nexport type ChannelMembersModeController = {\n mode: ChannelMembersViewMode;\n setMode: (mode: ChannelMembersViewMode) => void;\n};\n\nexport type ChannelMembersModeViewProps = {\n /**\n * Navigation surface for the mode. Call `modeController.setMode('browse')` to\n * return to the list, or any other mode key to transition between modes.\n */\n modeController: ChannelMembersModeController;\n};\n\nexport type ChannelMembersViewModeDescriptor = {\n /** Body rendered below the section header for this mode. */\n Body: React.ComponentType<ChannelMembersModeViewProps>;\n /**\n * Header title for this mode. A component (rather than a string) so it can pull\n * whatever it needs from context/hooks — member count, translation, etc.\n */\n Title: React.ComponentType;\n};\n\n/** Registry of modes, keyed by the mode string passed to `setMode`. */\nexport type ChannelMembersViewModes = Record<string, ChannelMembersViewModeDescriptor>;\n\n// `browse` (the default list) and `memberDetail` (selection-driven, renders its\n// own header) are handled by ChannelMembersView directly; every other mode —\n// built-in `add` or app-provided — is resolved from the mode-view registry.\nconst RESERVED_MODES: ChannelMembersViewMode[] = ['browse', 'memberDetail'];\n\nconst isReservedMode = (mode: ChannelMembersViewMode) => RESERVED_MODES.includes(mode);\n\nconst AddMembersModeTitle = () => {\n const { t } = useTranslationContext();\n return <>{t('Add members')}</>;\n};\n\n/** Built-in mode descriptors. Merged with (and overridable by) the `modeViews` prop. */\nexport const defaultChannelMembersModeViews: ChannelMembersViewModes = {\n add: {\n Body: ChannelMembersAddView,\n Title: AddMembersModeTitle,\n },\n};\n\nexport type ChannelMembersViewProps = SectionNavigatorSectionContentProps & {\n HeaderActions?: React.ComponentType<ChannelMembersHeaderActionsProps>;\n HeaderActionsMenuTrigger?: React.ComponentType<ChannelMembersHeaderActionsMenuTriggerProps>;\n headerActionSet?: ChannelMembersHeaderActionItem[];\n /** App-provided modes (e.g. bulk removal) rendered alongside the built-in ones. */\n modeViews?: ChannelMembersViewModes;\n};\n\nexport const ChannelMembersView = ({\n HeaderActions = DefaultHeaderActions,\n headerActionSet = defaultChannelMembersHeaderActionSet,\n HeaderActionsMenuTrigger,\n layout,\n modeViews: customModeViews,\n}: ChannelMembersViewProps) => {\n const { t } = useTranslationContext();\n const { channel } = useChannelDetailContext();\n const { close } = useModalContext();\n const [mode, setMode] = useState<ChannelMembersViewMode>('browse');\n const [selectedMember, setSelectedMember] = useState<ChannelMemberResponse>();\n const memberCount = useChannelMemberCount(channel);\n\n const modeViews = useMemo(\n () => ({ ...defaultChannelMembersModeViews, ...customModeViews }),\n [customModeViews],\n );\n\n const activeModeDescriptor = isReservedMode(mode) ? undefined : modeViews[mode];\n const isViewingMemberDetail = mode === 'memberDetail';\n\n const setViewMode = useCallback((nextMode: ChannelMembersViewMode) => {\n setMode(nextMode);\n if (nextMode !== 'memberDetail') {\n setSelectedMember(undefined);\n }\n }, []);\n\n // Fall back to the browse list if an unknown mode becomes active (e.g. the app\n // stops providing the mode's descriptor while it is selected).\n useEffect(() => {\n if (!isReservedMode(mode) && !modeViews[mode]) {\n setViewMode('browse');\n }\n }, [mode, modeViews, setViewMode]);\n\n const goBack = useCallback(() => setViewMode('browse'), [setViewMode]);\n\n const modeController = useMemo<ChannelMembersModeController>(\n () => ({\n mode,\n setMode: setViewMode,\n }),\n [mode, setViewMode],\n );\n\n const HeaderTrailingActions = useMemo(\n () =>\n function HeaderTrailingActions() {\n if (mode !== 'browse') return null;\n return (\n <HeaderActions\n headerActionSet={headerActionSet}\n HeaderActionsMenuTrigger={HeaderActionsMenuTrigger}\n modeController={modeController}\n />\n );\n },\n [HeaderActions, HeaderActionsMenuTrigger, modeController, headerActionSet, mode],\n );\n\n if (isViewingMemberDetail && selectedMember) {\n return (\n <ChannelMemberDetail layout={layout} member={selectedMember} onBack={goBack} />\n );\n }\n\n const ActiveModeTitle = activeModeDescriptor?.Title;\n const ActiveModeBody = activeModeDescriptor?.Body;\n\n return (\n <div className='str-chat__channel-detail__channel-members-view'>\n <SectionNavigatorHeader\n close={close}\n description={activeModeDescriptor ? undefined : t('Browse channel members')}\n goBack={activeModeDescriptor ? goBack : undefined}\n title={\n ActiveModeTitle ? (\n <ActiveModeTitle />\n ) : (\n t('{{ count }} members', { count: memberCount })\n )\n }\n TrailingContent={HeaderTrailingActions}\n />\n {ActiveModeBody ? (\n <ActiveModeBody modeController={modeController} />\n ) : (\n <ChannelMembersBrowseView\n onMemberSelect={(member) => {\n setSelectedMember(member);\n setViewMode('memberDetail');\n }}\n />\n )}\n </div>\n );\n};\n","import { IconPin } from '../../../../components/Icons';\nimport { useTranslationContext } from '../../../../context';\n\nexport const PinnedMessagesEmptyList = () => {\n const { t } = useTranslationContext();\n\n return (\n <div className='str-chat__channel-detail__pinned-messages-view__empty-state'>\n <IconPin className='str-chat__channel-detail__pinned-messages-view__empty-state__icon' />\n <div className='str-chat__channel-detail__pinned-messages-view__empty-state__content'>\n <p className='str-chat__channel-detail__pinned-messages-view__empty-state__title'>\n {t('No pinned messages')}\n </p>\n <p className='str-chat__channel-detail__pinned-messages-view__empty-state__description'>\n {t('Pin a message to see it here')}\n </p>\n </div>\n </div>\n );\n};\n","import { useEffect, useState } from 'react';\nimport type { Channel } from 'stream-chat';\n\n// stream-chat keeps channel.state.pinnedMessages current on these events (see\n// channel.ts `_handleChannelEvent` -> add/removePinnedMessage), but mutating that\n// array does not re-render React. Subscribing here re-reads the count so the view\n// re-renders — and re-reads channel.state directly — on every pin/unpin, not only\n// when the channel gains its first or loses its last pinned message.\nconst PINNED_MESSAGES_EVENTS = [\n 'message.new',\n 'message.updated',\n 'message.deleted',\n 'message.undeleted',\n] as const;\n\nconst getPinnedMessagesCount = (channel: Channel) =>\n channel.state?.pinnedMessages?.length ?? 0;\n\n/** Reactive count of the channel's pinned messages derived from channel state. */\nexport const usePinnedMessagesCount = (channel: Channel) => {\n const [pinnedMessagesCount, setPinnedMessagesCount] = useState(() =>\n getPinnedMessagesCount(channel),\n );\n\n useEffect(() => {\n const syncPinnedMessagesCount = () =>\n setPinnedMessagesCount(getPinnedMessagesCount(channel));\n\n syncPinnedMessagesCount();\n\n const subscriptions = PINNED_MESSAGES_EVENTS.map((event) =>\n channel.on(event, syncPinnedMessagesCount),\n );\n\n return () => subscriptions.forEach((subscription) => subscription.unsubscribe());\n }, [channel]);\n\n return pinnedMessagesCount;\n};\n","import {\n type LocalMessage,\n type MessageResponse,\n MessageSearchSource,\n type SearchSourceState,\n} from 'stream-chat';\nimport { useCallback, useEffect, useMemo } from 'react';\n\nimport { useChatContext } from '../../../../context';\nimport { useStateStore } from '../../../../store';\nimport { useChannelDetailContext } from '../../ChannelDetailContext';\nimport { usePinnedMessagesCount } from './usePinnedMessagesCount';\n\nconst PINNED_MESSAGES_SEARCH_PAGE_SIZE = 30;\nconst PINNED_MESSAGES_SEARCH_DEBOUNCE_MS = 300;\n\nconst pinnedMessagesSearchSourceItemsStateSelector = (\n state: SearchSourceState<MessageResponse>,\n) => ({\n messages: state.items,\n});\n\nexport type UsePinnedMessagesSearchParams = {\n /**\n * Custom message search source for pinned messages. When provided it is used\n * as-is — its filters and sort are respected, never overridden.\n */\n searchSource?: MessageSearchSource;\n};\n\nexport const usePinnedMessagesSearch = ({\n searchSource,\n}: UsePinnedMessagesSearchParams = {}) => {\n const { client } = useChatContext();\n const { channel } = useChannelDetailContext();\n const pinnedMessagesSearchSource = useMemo(() => {\n const source =\n searchSource ??\n new MessageSearchSource(\n client,\n {\n allowEmptySearchString: true,\n debounceMs: PINNED_MESSAGES_SEARCH_DEBOUNCE_MS,\n pageSize: PINNED_MESSAGES_SEARCH_PAGE_SIZE,\n resetOnNewSearchQuery: false,\n },\n {\n messageSearch: {\n initialFilterConfig: {\n text: {\n enabled: true,\n generate: ({ searchQuery }) =>\n searchQuery\n ? {\n text: { $autocomplete: searchQuery },\n }\n : null,\n },\n },\n },\n },\n );\n\n // Only configure a source we own; a provided source keeps its own filters\n // and sort.\n if (!searchSource) {\n source.messageSearchChannelFilters = { cid: channel.cid };\n source.messageSearchFilters = { pinned: true };\n }\n\n return source;\n }, [channel.cid, client, searchSource]);\n\n const { messages } = useStateStore(\n pinnedMessagesSearchSource.state,\n pinnedMessagesSearchSourceItemsStateSelector,\n );\n\n useEffect(() => {\n pinnedMessagesSearchSource.activate();\n\n return () => {\n pinnedMessagesSearchSource.cancelScheduledQuery();\n };\n }, [pinnedMessagesSearchSource]);\n\n // Query-independent flag, reactive to pin/unpin. The search source is the sole\n // source of the displayed list, but it does not know whether the channel has\n // pinned messages until a query resolves; this gates the search input, the\n // initial load and the empty-state choice (the channel can have pinned messages\n // that the current query matches none of).\n const hasPinnedMessages = usePinnedMessagesCount(channel) > 0;\n\n // The list is loaded and paginated entirely by the search source. Load the\n // first page once the channel is known to have pinned messages — gating on\n // hasPinnedMessages also loads page one when the channel gains its first pin\n // during the session.\n useEffect(() => {\n if (!hasPinnedMessages) return;\n void pinnedMessagesSearchSource.search('');\n }, [hasPinnedMessages, pinnedMessagesSearchSource]);\n\n const handleSearchChange = useCallback(\n (query: string) => {\n const trimmedQuery = query.trim();\n\n if (!trimmedQuery) {\n // Clearing the query reloads the full pinned list from its first page.\n pinnedMessagesSearchSource.cancelScheduledQuery();\n pinnedMessagesSearchSource.resetState();\n pinnedMessagesSearchSource.activate();\n void pinnedMessagesSearchSource.search('');\n return;\n }\n\n pinnedMessagesSearchSource.search(trimmedQuery);\n },\n [pinnedMessagesSearchSource],\n );\n\n return {\n displayedMessages: (messages ?? []) as Array<MessageResponse | LocalMessage>,\n handleSearchChange,\n hasPinnedMessages,\n hasSearchResultsLoaded: Array.isArray(messages),\n pinnedMessagesSearchSource,\n };\n};\n","import type { LocalMessage, MessageResponse, MessageSearchSource } from 'stream-chat';\nimport React, { useCallback, useMemo } from 'react';\n\nimport {\n useChannelActionContext,\n useChatContext,\n useModalContext,\n useTranslationContext,\n} from '../../../../context';\nimport { getDateString, isDate } from '../../../../i18n/utils';\nimport { Avatar } from '../../../../components/Avatar';\nimport { ListItemLayout } from '../../../../components/ListItemLayout';\nimport { VirtualizedList } from '../../VirtualizedList';\nimport { Prompt } from '../../../../components/Dialog';\nimport {\n SectionNavigatorHeader,\n type SectionNavigatorSectionContentProps,\n} from '../../SectionNavigator';\nimport { ChannelDetailSearchInput } from '../../ChannelDetailSearchInput';\nimport { getUserDisplayName } from '../ChannelMembersView/ChannelMembersView.utils';\nimport { ChannelDetailListLoadingIndicator } from '../../ChannelDetailListLoadingIndicator';\nimport { PinnedMessagesEmptyList } from './PinnedMessagesEmptyList';\nimport { usePinnedMessagesSearch } from './usePinnedMessagesSearch';\nimport { useChannelDetailContext } from '../../ChannelDetailContext';\nimport { ChannelDetailEmptyList } from '../../ChannelDetailEmptyList';\n\ntype PinnedMessage = MessageResponse | LocalMessage;\n\nconst computeItemKey = (_: number, message: PinnedMessage) => message.id;\n\nconst normalizeTimestamp = (timestamp: PinnedMessage['created_at']) => {\n if (!timestamp) return undefined;\n return isDate(timestamp) ? timestamp.toISOString() : timestamp;\n};\n\nconst getPinnedMessagePreview = (\n message: PinnedMessage,\n t: ReturnType<typeof useTranslationContext>['t'],\n) => {\n const text = message.text?.trim();\n if (text) return text;\n\n const attachment = message.attachments?.[0];\n const attachmentPreview =\n attachment?.title || attachment?.text || attachment?.fallback || attachment?.type;\n\n return attachmentPreview || t('Pinned message');\n};\n\nconst PinnedMessageDate = ({ message }: { message: PinnedMessage }) => {\n const { t, tDateTimeParser } = useTranslationContext('PinnedMessageDate');\n const normalizedTimestamp = normalizeTimestamp(message.created_at);\n\n const when = useMemo(\n () =>\n getDateString({\n messageCreatedAt: normalizedTimestamp,\n t,\n tDateTimeParser,\n timestampTranslationKey: 'timestamp/ChannelDetailPinnedMessageTimestamp',\n }),\n [normalizedTimestamp, t, tDateTimeParser],\n );\n\n if (!when) return null;\n\n return (\n <time\n className='str-chat__channel-detail__pinned-messages-view__list-item__date'\n dateTime={normalizedTimestamp}\n >\n {when}\n </time>\n );\n};\n\nconst PinnedMessagesViewItem = ({\n message,\n onSelect,\n}: {\n message: PinnedMessage;\n onSelect: (message: PinnedMessage) => void;\n}) => {\n const { t } = useTranslationContext();\n const displayName = getUserDisplayName(message.user ?? undefined);\n\n const LeadingSlot = useMemo(\n () =>\n function MessageAuthorAvatar() {\n return <Avatar imageUrl={message.user?.image} size='md' userName={displayName} />;\n },\n [displayName, message.user?.image],\n );\n\n const TrailingSlot = useMemo(\n () =>\n function MessageDate() {\n return <PinnedMessageDate message={message} />;\n },\n [message],\n );\n\n const rootProps = useMemo(\n () => ({\n className: 'str-chat__channel-detail__pinned-messages-view__list-item',\n onClick: () => onSelect(message),\n }),\n [message, onSelect],\n );\n\n return (\n <ListItemLayout\n LeadingSlot={LeadingSlot}\n RootElement='button'\n rootProps={rootProps}\n subtitle={getPinnedMessagePreview(message, t)}\n subtitleClassName='str-chat__channel-detail__pinned-messages-view__list-item__message-preview'\n title={displayName}\n TrailingSlot={TrailingSlot}\n />\n );\n};\n\nexport type PinnedMessagesViewProps = SectionNavigatorSectionContentProps & {\n /** Custom message search source for pinned messages. */\n searchSource?: MessageSearchSource;\n};\n\nexport const PinnedMessagesView: React.ComponentType<PinnedMessagesViewProps> = ({\n searchSource,\n}) => {\n const { setActiveChannel } = useChatContext();\n const { t } = useTranslationContext();\n const { close } = useModalContext();\n // fixme: it is not right to couple the ChannelDetail view with Channel component. We need to have access to channel.messagePaginator.jumpToMessage()\n const { jumpToMessage } = useChannelActionContext();\n const { channel } = useChannelDetailContext();\n const {\n displayedMessages,\n handleSearchChange,\n hasPinnedMessages,\n hasSearchResultsLoaded,\n pinnedMessagesSearchSource,\n } = usePinnedMessagesSearch({ searchSource });\n\n const handleSelectMessage = useCallback(\n (message: PinnedMessage) => {\n setActiveChannel(channel);\n jumpToMessage(message.id);\n close();\n },\n [channel, close, jumpToMessage, setActiveChannel],\n );\n\n const renderItem = useCallback(\n (_: number, message: PinnedMessage) => (\n <PinnedMessagesViewItem message={message} onSelect={handleSelectMessage} />\n ),\n [handleSelectMessage],\n );\n\n const EmptyPlaceholder = useMemo(\n () =>\n function PinnedMessagesEmptyPlaceholder() {\n if (!hasPinnedMessages) return <PinnedMessagesEmptyList />;\n if (hasSearchResultsLoaded)\n return (\n <ChannelDetailEmptyList>{t('No messages found')}</ChannelDetailEmptyList>\n );\n return null;\n },\n [hasPinnedMessages, hasSearchResultsLoaded, t],\n );\n\n const Footer = useMemo(\n () =>\n function PinnedMessagesListFooter() {\n return (\n <ChannelDetailListLoadingIndicator searchSource={pinnedMessagesSearchSource} />\n );\n },\n [pinnedMessagesSearchSource],\n );\n\n return (\n <div className='str-chat__channel-detail__pinned-messages-view'>\n <SectionNavigatorHeader\n close={close}\n description={t('Browse pinned messages')}\n title={t('Pinned messages')}\n />\n <Prompt.Body className='str-chat__channel-detail__pinned-messages-view__body'>\n {hasPinnedMessages && (\n <ChannelDetailSearchInput onSearchChange={handleSearchChange} />\n )}\n <VirtualizedList\n className='str-chat__channel-detail__pinned-messages-view__list'\n computeItemKey={computeItemKey}\n data={displayedMessages}\n EmptyPlaceholder={EmptyPlaceholder}\n Footer={Footer}\n itemContent={renderItem}\n loadNext={hasPinnedMessages ? pinnedMessagesSearchSource.search : undefined}\n />\n </Prompt.Body>\n </div>\n );\n};\n","import clsx from 'clsx';\nimport React, { useState } from 'react';\nimport type { Channel } from 'stream-chat';\n\nimport {\n SECTION_NAVIGATOR_LAYOUT,\n SectionNavigator,\n type SectionNavigatorLayout,\n type SectionNavigatorNavButtonProps,\n type SectionNavigatorProps,\n type SectionNavigatorSection,\n} from './SectionNavigator';\nimport { ChannelDetailNavButton } from './ChannelDetailNavButton';\nimport { ChannelDetailProvider } from './ChannelDetailContext';\nimport { ChannelFilesView } from './Views/ChannelFilesView';\nimport { ChannelManagementView } from './Views/ChannelManagementView';\nimport { ChannelMediaView } from './Views/ChannelMediaView';\nimport { ChannelMembersView } from './Views/ChannelMembersView';\nimport { PinnedMessagesView } from './Views/PinnedMessagesView';\nimport { Prompt } from '../../components/Dialog';\nimport {\n IconFolder,\n IconImage,\n IconInfo,\n IconPin,\n IconUser,\n} from '../../components/Icons';\n\nconst ChannelManagementNavButtonIcon = () => (\n <IconInfo className='str-chat__channel-detail__action-icon' />\n);\n\nconst ChannelMembersNavButtonIcon = () => (\n <IconUser className='str-chat__channel-detail__action-icon' />\n);\n\nconst PinnedMessagesNavButtonIcon = () => (\n <IconPin className='str-chat__channel-detail__action-icon' />\n);\n\nconst ChannelMediaNavButtonIcon = () => (\n <IconImage className='str-chat__channel-detail__action-icon' />\n);\n\nconst ChannelFilesNavButtonIcon = () => (\n <IconFolder className='str-chat__channel-detail__action-icon' />\n);\n\nexport const ChannelManagementNavButton = (props: SectionNavigatorNavButtonProps) => (\n <ChannelDetailNavButton\n {...props}\n LeadingIcon={ChannelManagementNavButtonIcon}\n title='Channel info'\n />\n);\n\nexport const ChannelMembersNavButton = (props: SectionNavigatorNavButtonProps) => (\n <ChannelDetailNavButton\n {...props}\n LeadingIcon={ChannelMembersNavButtonIcon}\n title='Members'\n />\n);\n\nexport const PinnedMessagesNavButton = (props: SectionNavigatorNavButtonProps) => (\n <ChannelDetailNavButton\n {...props}\n LeadingIcon={PinnedMessagesNavButtonIcon}\n title='Pinned messages'\n />\n);\n\nexport const ChannelMediaNavButton = (props: SectionNavigatorNavButtonProps) => (\n <ChannelDetailNavButton\n {...props}\n LeadingIcon={ChannelMediaNavButtonIcon}\n title='Photos & videos'\n />\n);\n\nexport const ChannelFilesNavButton = (props: SectionNavigatorNavButtonProps) => (\n <ChannelDetailNavButton\n {...props}\n LeadingIcon={ChannelFilesNavButtonIcon}\n title='Files'\n />\n);\n\nexport const defaultChannelDetailSections: SectionNavigatorSection[] = [\n {\n id: 'channel-info',\n NavButton: ChannelManagementNavButton,\n SectionContent: ChannelManagementView,\n },\n {\n id: 'channel-members',\n NavButton: ChannelMembersNavButton,\n SectionContent: ChannelMembersView,\n },\n {\n id: 'pinned-messages',\n NavButton: PinnedMessagesNavButton,\n SectionContent: PinnedMessagesView,\n },\n {\n id: 'channel-media',\n NavButton: ChannelMediaNavButton,\n SectionContent: ChannelMediaView,\n },\n {\n id: 'channel-files',\n NavButton: ChannelFilesNavButton,\n SectionContent: ChannelFilesView,\n },\n];\n\nexport type ChannelDetailProps = Omit<SectionNavigatorProps, 'sections'> & {\n channel: Channel;\n sections?: SectionNavigatorSection[];\n};\n\nexport const ChannelDetail = ({\n channel,\n className,\n defaultLayout = SECTION_NAVIGATOR_LAYOUT.tabs,\n sections = defaultChannelDetailSections,\n ...props\n}: ChannelDetailProps) => {\n const [layout, setLayout] = useState<SectionNavigatorLayout>(defaultLayout);\n\n return (\n <ChannelDetailProvider channel={channel}>\n <Prompt.Root\n className={clsx(\n 'str-chat__channel-detail',\n {\n 'str-chat__channel-detail--inline':\n layout === SECTION_NAVIGATOR_LAYOUT.inline,\n },\n className,\n )}\n >\n <SectionNavigator\n {...props}\n defaultLayout={defaultLayout}\n onLayoutChange={setLayout}\n sections={sections}\n />\n </Prompt.Root>\n </ChannelDetailProvider>\n );\n};\n","import clsx from 'clsx';\nimport React, { useCallback, useState } from 'react';\n\nimport {\n useChannelStateContext,\n useComponentContext,\n useTranslationContext,\n} from '../../context';\nimport {\n type ChannelAvatarProps,\n ChannelAvatar as DefaultChannelAvatar,\n} from '../../components/Avatar/index';\nimport {\n type ChannelDetailProps,\n ChannelDetail as DefaultChannelDetail,\n} from './ChannelDetail';\nimport { GlobalModal } from '../../components/Modal';\n\nexport type AvatarWithChannelDetailProps = ChannelAvatarProps & {\n Avatar?: React.ComponentType<ChannelAvatarProps>;\n ChannelDetail?: React.ComponentType<ChannelDetailProps>;\n};\n\nconst avatarWithChannelDetailDialogRootProps = {\n className: 'str-chat__channel-detail-modal',\n};\n\nexport const AvatarWithChannelDetail = ({\n Avatar,\n ChannelDetail = DefaultChannelDetail,\n className,\n ...avatarProps\n}: AvatarWithChannelDetailProps) => {\n const { t } = useTranslationContext();\n const { channel } = useChannelStateContext();\n const { Avatar: ContextAvatar, Modal = GlobalModal } = useComponentContext();\n const [isModalOpen, setIsModalOpen] = useState(false);\n\n const openModal = useCallback(() => setIsModalOpen(true), []);\n const closeModal = useCallback(() => setIsModalOpen(false), []);\n\n const AvatarComponent =\n Avatar ??\n (ContextAvatar === AvatarWithChannelDetail ? undefined : ContextAvatar) ??\n DefaultChannelAvatar;\n\n return (\n <>\n <button\n aria-label={t('aria/Open channel details')}\n className='str-chat__avatar-with-channel-detail-button'\n onClick={openModal}\n type='button'\n >\n <AvatarComponent\n {...avatarProps}\n className={clsx(\n 'str-chat__avatar-with-channel-detail-button__avatar',\n className,\n )}\n />\n </button>\n <Modal\n aria-label={t('aria/Channel details')}\n dialogRootProps={avatarWithChannelDetailDialogRootProps}\n onClose={closeModal}\n open={isModalOpen}\n >\n <ChannelDetail channel={channel} />\n </Modal>\n </>\n );\n};\n"],"mappings":"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"}
|