53 lines
2.3 KiB
TypeScript
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>
|
|
);
|
|
}
|