add thirdparty instance filter in server explore

This commit is contained in:
Ajay Bura 2024-03-17 20:20:20 +05:30
parent a34dd031d0
commit f1b96c13fd
2 changed files with 127 additions and 0 deletions

View file

@ -15,7 +15,9 @@ import {
Icon, Icon,
Icons, Icons,
Input, Input,
Line,
Menu, Menu,
MenuItem,
PopOut, PopOut,
Scroll, Scroll,
Spinner, Spinner,
@ -37,12 +39,14 @@ import { getExploreServerPath, withSearchParam } from '../../pathUtils';
import * as css from './style.css'; import * as css from './style.css';
import { allRoomsAtom } from '../../../state/room-list/roomList'; import { allRoomsAtom } from '../../../state/room-list/roomList';
import { useRoomNavigate } from './hooks'; import { useRoomNavigate } from './hooks';
import { getMxIdServer } from '../../../utils/matrix';
const getServerSearchParams = (searchParams: URLSearchParams): ExploreServerPathSearchParams => ({ const getServerSearchParams = (searchParams: URLSearchParams): ExploreServerPathSearchParams => ({
limit: searchParams.get('limit') ?? undefined, limit: searchParams.get('limit') ?? undefined,
since: searchParams.get('since') ?? undefined, since: searchParams.get('since') ?? undefined,
term: searchParams.get('term') ?? undefined, term: searchParams.get('term') ?? undefined,
type: searchParams.get('type') ?? undefined, type: searchParams.get('type') ?? undefined,
instance: searchParams.get('instance') ?? undefined,
}); });
type RoomTypeFilter = { type RoomTypeFilter = {
@ -132,6 +136,106 @@ function Search({ active, loading, searchInputRef, onSearch, onReset }: SearchPr
); );
} }
const DEFAULT_INSTANCE_NAME = 'Matrix';
function ThirdPartyProtocolsSelector({
instanceId,
onChange,
}: {
instanceId?: string;
onChange: (instanceId?: string) => void;
}) {
const mx = useMatrixClient();
const [menu, setMenu] = useState(false);
const { data } = useQuery({
queryKey: ['thirdparty', 'protocols'],
queryFn: () => mx.getThirdpartyProtocols(),
});
const handleInstanceSelect: MouseEventHandler<HTMLButtonElement> = (evt): void => {
const insId = evt.currentTarget.getAttribute('data-instance-id') ?? undefined;
onChange(insId);
setMenu(false);
};
const instances = data && Object.keys(data).flatMap((protocol) => data[protocol].instances);
if (!instances || instances.length === 0) return null;
const selectedInstance = instances.find((instance) => instanceId === instance.instance_id);
return (
<PopOut
open={menu}
align="End"
position="Bottom"
content={
<FocusTrap
focusTrapOptions={{
initialFocus: false,
onDeactivate: () => setMenu(false),
clickOutsideDeactivates: true,
}}
>
<Menu variant="Surface">
<Box
direction="Column"
gap="100"
style={{ padding: config.space.S100, minWidth: toRem(100) }}
>
<Text style={{ padding: config.space.S100 }} size="L400" truncate>
Protocols
</Text>
<Box direction="Column">
<MenuItem
size="300"
variant="Surface"
aria-pressed={instanceId === undefined}
radii="300"
onClick={handleInstanceSelect}
>
<Text size="T200" truncate>
{DEFAULT_INSTANCE_NAME}
</Text>
</MenuItem>
{instances.map((instance) => (
<MenuItem
size="300"
key={instance.instance_id}
data-instance-id={instance.instance_id}
aria-pressed={instanceId === instance.instance_id}
variant="Surface"
radii="300"
onClick={handleInstanceSelect}
>
<Text size="T200" truncate>
{instance.desc}
</Text>
</MenuItem>
))}
</Box>
</Box>
</Menu>
</FocusTrap>
}
>
{(anchorRef) => (
<Chip
ref={anchorRef}
onClick={() => setMenu(!menu)}
aria-pressed={menu}
radii="Pill"
size="400"
variant={instanceId ? 'Success' : 'SurfaceVariant'}
after={<Icon size="100" src={Icons.ChevronBottom} />}
>
<Text size="T200" truncate>
{selectedInstance?.desc ?? DEFAULT_INSTANCE_NAME}
</Text>
</Chip>
)}
</PopOut>
);
}
type LimitButtonProps = { type LimitButtonProps = {
limit: number; limit: number;
onLimitChange: (limit: string) => void; onLimitChange: (limit: string) => void;
@ -227,6 +331,8 @@ function LimitButton({ limit, onLimitChange }: LimitButtonProps) {
export function PublicRooms() { export function PublicRooms() {
const { server } = useParams(); const { server } = useParams();
const mx = useMatrixClient(); const mx = useMatrixClient();
const userId = mx.getUserId();
const userServer = userId && getMxIdServer(userId);
const allRooms = useAtomValue(allRoomsAtom); const allRooms = useAtomValue(allRoomsAtom);
const { navigateSpace, navigateRoom } = useRoomNavigate(); const { navigateSpace, navigateRoom } = useRoomNavigate();
@ -270,6 +376,7 @@ export function PublicRooms() {
generic_search_term: serverSearchParams.term, generic_search_term: serverSearchParams.term,
room_types: roomType !== undefined ? [roomType] : undefined, room_types: roomType !== undefined ? [roomType] : undefined,
}, },
third_party_instance_id: serverSearchParams.instance,
} }
); );
}, [mx, server, serverSearchParams]); }, [mx, server, serverSearchParams]);
@ -282,6 +389,7 @@ export function PublicRooms() {
serverSearchParams.since, serverSearchParams.since,
serverSearchParams.term, serverSearchParams.term,
serverSearchParams.type, serverSearchParams.type,
serverSearchParams.instance,
], ],
queryFn: fetchPublicRooms, queryFn: fetchPublicRooms,
}); });
@ -343,6 +451,10 @@ export function PublicRooms() {
explore({ limit }); explore({ limit });
}; };
const handleInstanceIdChange = (instanceId?: string) => {
explore({ instance: instanceId });
};
return ( return (
<Page> <Page>
<PageHeader> <PageHeader>
@ -415,6 +527,20 @@ export function PublicRooms() {
<Text size="T200">{filter.title}</Text> <Text size="T200">{filter.title}</Text>
</Chip> </Chip>
))} ))}
{userServer === server && (
<>
<Line
style={{ margin: `${config.space.S100} 0` }}
direction="Vertical"
variant="Surface"
size="300"
/>
<ThirdPartyProtocolsSelector
instanceId={serverSearchParams.instance}
onChange={handleInstanceIdChange}
/>
</>
)}
<Box grow="Yes" data-spacing-node /> <Box grow="Yes" data-spacing-node />
<LimitButton limit={currentLimit} onLimitChange={handleLimitChange} /> <LimitButton limit={currentLimit} onLimitChange={handleLimitChange} />
</Box> </Box>

View file

@ -50,6 +50,7 @@ export type ExploreServerPathSearchParams = {
since?: string; since?: string;
term?: string; term?: string;
type?: string; type?: string;
instance?: string;
}; };
export const EXPLORE_SERVER_PATH = `/explore/${_SERVER_PATH}`; export const EXPLORE_SERVER_PATH = `/explore/${_SERVER_PATH}`;