vojo/src/app/pages/client/bots/Bots.tsx

53 lines
2.3 KiB
TypeScript

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 <BotCard preset={preset} selected={selected} />;
}
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<HTMLDivElement>(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 (
<PageNav resizable surface={inPagerMode ? undefined : 'surfaceVariant'}>
<StreamHeader scrollRef={scrollRef} pinKey="bots">
<PageNavContent scrollRef={scrollRef}>
<Box
direction="Column"
gap="100"
style={{
padding: `${toRem(6)} ${config.space.S100}`,
borderBottom: `${config.borderWidth.B300} solid ${color.Surface.ContainerLine}`,
}}
>
{bots.map((preset) => (
<BotRow key={preset.id} preset={preset} />
))}
</Box>
</PageNavContent>
</StreamHeader>
</PageNav>
);
}