0c6003fb87
Two review agents found the preview card degrades to 'id + logo + Join' for real
reasons. Fixes:
- **via was dropped at the summary fetch** (root cause). RoomSummaryLoader now
accepts + forwards `via` to getRoomSummary (and keys the query on it);
JoinBeforeNavigate passes viaServers; the lobby Preview chip carries data-via and
Lobby.handleOpenRoom appends it to the navigated URL. Without this, previews of
rooms the HS isn't already in came back sparse/404.
- **No loading/error state** -> RoomSummaryLoader now surfaces {loading,error};
JoinBeforeNavigate shows a Spinner while loading instead of the degraded card.
- **Room id leaked as name AND topic AND header** -> stop using the raw `!id` as
the topic fallback (show 'No description'); name falls back to canonical_alias
then alias-localpart; the page header shows the summary name.
- **Richer, membership-aware card**: forward canonical_alias (shown under the name),
world_readable ('Readable' badge), and membership -> the button now shows Accept
invite / Requested / Banned correctly instead of a Join that lies; a 'hero' layout
for the single-preview page (primary Join button, unclamped topic). Removed dead
`|| undefined ||`.
IRoomSummary re-adds canonical_alias (the SDK type Omit<>s it though MSC3266
returns it). 738 tests pass, build clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
100 lines
3.9 KiB
TypeScript
100 lines
3.9 KiB
TypeScript
import React from 'react';
|
|
import { Box, Icon, IconButton, Icons, Scroll, Spinner, Text, toRem } from 'folds';
|
|
import { useAtomValue } from 'jotai';
|
|
import { RoomCard } from '../../components/room-card';
|
|
import { RoomTopicViewer } from '../../components/room-topic-viewer';
|
|
import { Page, PageHeader } from '../../components/page';
|
|
import { RoomSummaryLoader } from '../../components/RoomSummaryLoader';
|
|
import { useRoomNavigate } from '../../hooks/useRoomNavigate';
|
|
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
|
import { allRoomsAtom } from '../../state/room-list/roomList';
|
|
import { ScreenSize, useScreenSizeContext } from '../../hooks/useScreenSize';
|
|
import { BackRouteHandler } from '../../components/BackRouteHandler';
|
|
|
|
type JoinBeforeNavigateProps = { roomIdOrAlias: string; eventId?: string; viaServers?: string[] };
|
|
export function JoinBeforeNavigate({
|
|
roomIdOrAlias,
|
|
eventId,
|
|
viaServers,
|
|
}: JoinBeforeNavigateProps) {
|
|
const mx = useMatrixClient();
|
|
const allRooms = useAtomValue(allRoomsAtom);
|
|
const { navigateRoom, navigateSpace } = useRoomNavigate();
|
|
const screenSize = useScreenSizeContext();
|
|
|
|
const handleView = (roomId: string) => {
|
|
if (mx.getRoom(roomId)?.isSpaceRoom()) {
|
|
navigateSpace(roomId);
|
|
return;
|
|
}
|
|
navigateRoom(roomId, eventId);
|
|
};
|
|
|
|
return (
|
|
<Page>
|
|
<RoomSummaryLoader roomIdOrAlias={roomIdOrAlias} via={viaServers}>
|
|
{(summary, state) => (
|
|
<>
|
|
<PageHeader balance>
|
|
<Box grow="Yes" gap="200">
|
|
<Box shrink="No">
|
|
{screenSize === ScreenSize.Mobile && (
|
|
<BackRouteHandler>
|
|
{(onBack) => (
|
|
<IconButton onClick={onBack} aria-label="Back">
|
|
<Icon src={Icons.ArrowLeft} />
|
|
</IconButton>
|
|
)}
|
|
</BackRouteHandler>
|
|
)}
|
|
</Box>
|
|
<Box grow="Yes" justifyContent="Center" alignItems="Center" gap="200">
|
|
<Text size="H3" truncate>
|
|
{summary?.name || summary?.canonical_alias || roomIdOrAlias}
|
|
</Text>
|
|
</Box>
|
|
</Box>
|
|
</PageHeader>
|
|
<Box grow="Yes">
|
|
<Scroll hideTrack visibility="Hover" size="0">
|
|
<Box
|
|
style={{ height: '100%' }}
|
|
grow="Yes"
|
|
alignItems="Center"
|
|
justifyContent="Center"
|
|
>
|
|
{state.loading && !summary ? (
|
|
<Spinner size="600" variant="Secondary" />
|
|
) : (
|
|
<RoomCard
|
|
hero
|
|
style={{ maxWidth: toRem(420), width: '100%' }}
|
|
roomIdOrAlias={roomIdOrAlias}
|
|
allRooms={allRooms}
|
|
avatarUrl={summary?.avatar_url}
|
|
name={summary?.name}
|
|
canonicalAlias={summary?.canonical_alias}
|
|
topic={summary?.topic}
|
|
memberCount={summary?.num_joined_members}
|
|
roomType={summary?.room_type}
|
|
joinRule={summary?.join_rule}
|
|
encrypted={!!summary?.['im.nheko.summary.encryption']}
|
|
worldReadable={summary?.world_readable}
|
|
membership={summary?.membership}
|
|
viaServers={viaServers}
|
|
renderTopicViewer={(name, topic, requestClose) => (
|
|
<RoomTopicViewer name={name} topic={topic} requestClose={requestClose} />
|
|
)}
|
|
onView={handleView}
|
|
/>
|
|
)}
|
|
</Box>
|
|
</Scroll>
|
|
</Box>
|
|
</>
|
|
)}
|
|
</RoomSummaryLoader>
|
|
</Page>
|
|
);
|
|
}
|