mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-02-23 21:53:05 +01:00
add thirdparty instance filter in server explore
This commit is contained in:
parent
a34dd031d0
commit
f1b96c13fd
2 changed files with 127 additions and 0 deletions
|
@ -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>
|
||||||
|
|
|
@ -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}`;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue