fix(channels): collapse /channels/ index into one mobile pane and add Create-community CTA next to Find-community on empty state
This commit is contained in:
parent
f2ecca64da
commit
2d101a40fc
5 changed files with 31 additions and 18 deletions
|
|
@ -78,8 +78,8 @@ export function PageRoot({ nav, children }: PageRootProps) {
|
|||
TL/BL carves expose the outer's void. The explicit
|
||||
Background bg on the inner is what keeps the panel's
|
||||
apparent colour unchanged for routes whose content has no
|
||||
opaque bg of its own (e.g. ChannelsLanding) — without it
|
||||
the outer void would bleed through. */}
|
||||
opaque bg of its own — without it the outer void would
|
||||
bleed through. */}
|
||||
<Box grow="Yes" style={{ minWidth: 0, backgroundColor: VOJO_HORSESHOE_VOID_COLOR }}>
|
||||
<Box
|
||||
grow="Yes"
|
||||
|
|
|
|||
|
|
@ -54,12 +54,7 @@ import { ClientBindAtoms, ClientLayout, ClientRoot } from './client';
|
|||
import { HomeRouteRoomProvider } from './client/home';
|
||||
import { Direct, DirectCreate, DirectRouteRoomProvider } from './client/direct';
|
||||
import { BotExperienceHost, Bots } from './client/bots';
|
||||
import {
|
||||
Channels,
|
||||
ChannelsRootNav,
|
||||
ChannelPickPlaceholder,
|
||||
ChannelsLanding,
|
||||
} from './client/channels';
|
||||
import { Channels, ChannelsRootNav, ChannelPickPlaceholder } from './client/channels';
|
||||
import { RouteSpaceProvider, Space, SpaceRouteRoomProvider, SpaceSearch } from './client/space';
|
||||
import { Explore, FeaturedRooms, PublicRooms } from './client/explore';
|
||||
import { setAfterLoginRedirectPath } from './afterLoginRedirectPath';
|
||||
|
|
@ -302,7 +297,7 @@ export const createRouter = (clientConfig: ClientConfig, screenSize: ScreenSize)
|
|||
</MobileFriendlyPageNav>
|
||||
}
|
||||
>
|
||||
<ChannelsLanding />
|
||||
{mobile ? null : <WelcomePage />}
|
||||
</PageRoot>
|
||||
}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -4,24 +4,31 @@ import { PageNav, PageNavContent } from '../../../components/page';
|
|||
import { StreamHeader } from '../../../components/stream-header';
|
||||
import { ChannelsList } from './ChannelsList';
|
||||
import { ChannelCreateRow } from './ChannelCreateRow';
|
||||
import { ChannelsLanding } from './ChannelsLanding';
|
||||
import { ChannelsWorkspaceHorseshoe } from './ChannelsWorkspaceHorseshoe';
|
||||
import { WorkspaceFooter } from './WorkspaceFooter';
|
||||
import { ACTIVE_SPACE_KEY } from './useActiveSpace';
|
||||
|
||||
// Index route at /channels/ (no space selected). Renders the shared
|
||||
// StreamHeader so the segment switcher is consistent across surfaces,
|
||||
// but no list/footer — those need a Space context.
|
||||
// StreamHeader (segment switcher) plus the resolve-active-space-or-
|
||||
// show-empty-state body — same pattern as Direct's nav owning its own
|
||||
// empty state. Keeping the landing inside the nav avoids rendering it
|
||||
// as a sibling pane: on mobile both would collide into one screen, and
|
||||
// on desktop the redirect logic would fire twice if mounted twice.
|
||||
//
|
||||
// `<ChannelsLanding />` is mounted **directly** as the curtain's flex
|
||||
// child (NOT wrapped in `PageNavContent`). `NavEmptyCenter` relies on
|
||||
// `flexGrow:1 + justifyContent:Center` for vertical centering — the
|
||||
// curtain stage is `display:flex; flex-direction:column`, so direct
|
||||
// mount gives the empty state the height it needs to center. Wrapping
|
||||
// it in `PageNavContent` (block layout inside Scroll) would collapse
|
||||
// the centering to top-aligned. Same idiom as `Direct.tsx::DirectEmpty`.
|
||||
export function ChannelsRootNav() {
|
||||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
return (
|
||||
<PageNav resizable surface="surfaceVariant">
|
||||
<StreamHeader scrollRef={scrollRef}>
|
||||
<PageNavContent scrollRef={scrollRef}>
|
||||
{/* Empty list slot is intentional: StreamHeader needs a real
|
||||
scroll target on this route for its touch gesture even
|
||||
though there's no list yet. */}
|
||||
<div />
|
||||
</PageNavContent>
|
||||
<ChannelsLanding />
|
||||
</StreamHeader>
|
||||
</PageNav>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { Box, Button, Icon, Icons, Text } from 'folds';
|
|||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||
import { allRoomsAtom } from '../../../state/room-list/roomList';
|
||||
import { useOrphanSpaces } from '../../../state/hooks/roomList';
|
||||
import { useOpenCreateSpaceModal } from '../../../state/hooks/createSpaceModal';
|
||||
import { roomToParentsAtom } from '../../../state/room/roomToParents';
|
||||
import { getCanonicalAliasOrRoomId } from '../../../utils/matrix';
|
||||
import { getChannelsSpacePath, getExplorePath } from '../../pathUtils';
|
||||
|
|
@ -19,6 +20,7 @@ export function ChannelsLanding() {
|
|||
const mx = useMatrixClient();
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const openCreateSpaceModal = useOpenCreateSpaceModal();
|
||||
const roomToParents = useAtomValue(roomToParentsAtom);
|
||||
const orphanSpaces = useOrphanSpaces(mx, allRoomsAtom, roomToParents);
|
||||
const activeSpaceId = useActiveSpace(orphanSpaces);
|
||||
|
|
@ -49,6 +51,16 @@ export function ChannelsLanding() {
|
|||
{t('Channels.explore_cta')}
|
||||
</Text>
|
||||
</Button>
|
||||
<Button
|
||||
variant="Secondary"
|
||||
fill="Soft"
|
||||
size="300"
|
||||
onClick={() => openCreateSpaceModal()}
|
||||
>
|
||||
<Text size="B300" truncate>
|
||||
{t('Channels.workspace_switcher_create_space')}
|
||||
</Text>
|
||||
</Button>
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
export * from './Channels';
|
||||
export * from './ChannelsList';
|
||||
export * from './ChannelsLanding';
|
||||
export * from './ChannelPickPlaceholder';
|
||||
export * from './useActiveSpace';
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue