fix: zulip stream and topic selection in share dialog (#644)

* fix: zulip stream and topic selection in share dialog

Replace useListCollection with createListCollection to match the working
room edit implementation. This ensures collections update when data loads,
fixing the issue where streams and topics wouldn't appear until navigation.

* fix: wrap createListCollection in useMemo to prevent recreation on every render

Both streamCollection and topicCollection are now memoized to improve performance
and prevent unnecessary re-renders of Combobox components
This commit is contained in:
2025-09-15 12:34:51 -06:00
committed by GitHub
parent 3f1fe8c9bf
commit c546e69739

View File

@@ -14,8 +14,7 @@ import {
Checkbox, Checkbox,
Combobox, Combobox,
Spinner, Spinner,
useFilter, createListCollection,
useListCollection,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { TbBrandZulip } from "react-icons/tb"; import { TbBrandZulip } from "react-icons/tb";
import { import {
@@ -48,8 +47,6 @@ export default function ShareZulip(props: ShareZulipProps & BoxProps) {
const { data: topics = [] } = useZulipTopics(selectedStreamId); const { data: topics = [] } = useZulipTopics(selectedStreamId);
const postToZulipMutation = useTranscriptPostToZulip(); const postToZulipMutation = useTranscriptPostToZulip();
const { contains } = useFilter({ sensitivity: "base" });
const streamItems = useMemo(() => { const streamItems = useMemo(() => {
return streams.map((stream: Stream) => ({ return streams.map((stream: Stream) => ({
label: stream.name, label: stream.name,
@@ -64,17 +61,21 @@ export default function ShareZulip(props: ShareZulipProps & BoxProps) {
})); }));
}, [topics]); }, [topics]);
const { collection: streamItemsCollection, filter: streamItemsFilter } = const streamCollection = useMemo(
useListCollection({ () =>
initialItems: streamItems, createListCollection({
filter: contains, items: streamItems,
}); }),
[streamItems],
);
const { collection: topicItemsCollection, filter: topicItemsFilter } = const topicCollection = useMemo(
useListCollection({ () =>
initialItems: topicItems, createListCollection({
filter: contains, items: topicItems,
}); }),
[topicItems],
);
// Update selected stream ID when stream changes // Update selected stream ID when stream changes
useEffect(() => { useEffect(() => {
@@ -156,15 +157,12 @@ export default function ShareZulip(props: ShareZulipProps & BoxProps) {
<Flex align="center" gap={2}> <Flex align="center" gap={2}>
<Text>#</Text> <Text>#</Text>
<Combobox.Root <Combobox.Root
collection={streamItemsCollection} collection={streamCollection}
value={stream ? [stream] : []} value={stream ? [stream] : []}
onValueChange={(e) => { onValueChange={(e) => {
setTopic(undefined); setTopic(undefined);
setStream(e.value[0]); setStream(e.value[0]);
}} }}
onInputValueChange={(e) =>
streamItemsFilter(e.inputValue)
}
openOnClick={true} openOnClick={true}
positioning={{ positioning={{
strategy: "fixed", strategy: "fixed",
@@ -181,7 +179,7 @@ export default function ShareZulip(props: ShareZulipProps & BoxProps) {
<Combobox.Positioner> <Combobox.Positioner>
<Combobox.Content> <Combobox.Content>
<Combobox.Empty>No streams found</Combobox.Empty> <Combobox.Empty>No streams found</Combobox.Empty>
{streamItemsCollection.items.map((item) => ( {streamItems.map((item) => (
<Combobox.Item key={item.value} item={item}> <Combobox.Item key={item.value} item={item}>
{item.label} {item.label}
</Combobox.Item> </Combobox.Item>
@@ -197,12 +195,9 @@ export default function ShareZulip(props: ShareZulipProps & BoxProps) {
<Flex align="center" gap={2}> <Flex align="center" gap={2}>
<Text visibility="hidden">#</Text> <Text visibility="hidden">#</Text>
<Combobox.Root <Combobox.Root
collection={topicItemsCollection} collection={topicCollection}
value={topic ? [topic] : []} value={topic ? [topic] : []}
onValueChange={(e) => setTopic(e.value[0])} onValueChange={(e) => setTopic(e.value[0])}
onInputValueChange={(e) =>
topicItemsFilter(e.inputValue)
}
openOnClick openOnClick
selectionBehavior="replace" selectionBehavior="replace"
skipAnimationOnMount={true} skipAnimationOnMount={true}
@@ -222,7 +217,7 @@ export default function ShareZulip(props: ShareZulipProps & BoxProps) {
<Combobox.Positioner> <Combobox.Positioner>
<Combobox.Content> <Combobox.Content>
<Combobox.Empty>No topics found</Combobox.Empty> <Combobox.Empty>No topics found</Combobox.Empty>
{topicItemsCollection.items.map((item) => ( {topicItems.map((item) => (
<Combobox.Item key={item.value} item={item}> <Combobox.Item key={item.value} item={item}>
{item.label} {item.label}
<Combobox.ItemIndicator /> <Combobox.ItemIndicator />