import React, { useRef } from 'react'; import { Box, color, config, toRem } from 'folds'; import { useMatch } from 'react-router-dom'; import { PageNav, PageNavContent } from '../../../components/page'; import { StreamHeader } from '../../../components/stream-header'; import { useMobilePagerPane } from '../../../components/mobile-tabs-pager/MobilePagerPaneContext'; import { useBotPresets } from '../../../features/bots/catalog'; import type { BotPreset } from '../../../features/bots/catalog'; import { BotCard } from '../../../features/bots/BotCard'; import { BOTS_BOT_PATH } from '../../paths'; // Static preset links only. Room discovery belongs to /bots/:botId so the // list doesn't install Matrix listeners or scan rooms for every catalog entry. function BotRow({ preset }: { preset: BotPreset }) { // `end: false` so future child routes under :botId keep the parent card // selected. RR-v6 already URL-decodes `params.botId`, no extra decode here. const match = useMatch({ path: BOTS_BOT_PATH, caseSensitive: true, end: false }); const selected = match?.params.botId === preset.id; return ; } export function Bots() { const bots = useBotPresets(); // `scrollRef` is passed to the header so the touch gesture (native // only) can recognise list scrollTop=0 and engage the curtain peek. // Icons + click flows work on every platform regardless. const scrollRef = useRef(null); // Skip PageNav surface in pager mode — see Direct.tsx for the // rationale; the static header behind the strip owns the visible // safe-top + tabsRow tone. const inPagerMode = useMobilePagerPane() !== null; return ( {bots.map((preset) => ( ))} ); }