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
|
TL/BL carves expose the outer's void. The explicit
|
||||||
Background bg on the inner is what keeps the panel's
|
Background bg on the inner is what keeps the panel's
|
||||||
apparent colour unchanged for routes whose content has no
|
apparent colour unchanged for routes whose content has no
|
||||||
opaque bg of its own (e.g. ChannelsLanding) — without it
|
opaque bg of its own — without it the outer void would
|
||||||
the outer void would bleed through. */}
|
bleed through. */}
|
||||||
<Box grow="Yes" style={{ minWidth: 0, backgroundColor: VOJO_HORSESHOE_VOID_COLOR }}>
|
<Box grow="Yes" style={{ minWidth: 0, backgroundColor: VOJO_HORSESHOE_VOID_COLOR }}>
|
||||||
<Box
|
<Box
|
||||||
grow="Yes"
|
grow="Yes"
|
||||||
|
|
|
||||||
|
|
@ -54,12 +54,7 @@ import { ClientBindAtoms, ClientLayout, ClientRoot } from './client';
|
||||||
import { HomeRouteRoomProvider } from './client/home';
|
import { HomeRouteRoomProvider } from './client/home';
|
||||||
import { Direct, DirectCreate, DirectRouteRoomProvider } from './client/direct';
|
import { Direct, DirectCreate, DirectRouteRoomProvider } from './client/direct';
|
||||||
import { BotExperienceHost, Bots } from './client/bots';
|
import { BotExperienceHost, Bots } from './client/bots';
|
||||||
import {
|
import { Channels, ChannelsRootNav, ChannelPickPlaceholder } from './client/channels';
|
||||||
Channels,
|
|
||||||
ChannelsRootNav,
|
|
||||||
ChannelPickPlaceholder,
|
|
||||||
ChannelsLanding,
|
|
||||||
} from './client/channels';
|
|
||||||
import { RouteSpaceProvider, Space, SpaceRouteRoomProvider, SpaceSearch } from './client/space';
|
import { RouteSpaceProvider, Space, SpaceRouteRoomProvider, SpaceSearch } from './client/space';
|
||||||
import { Explore, FeaturedRooms, PublicRooms } from './client/explore';
|
import { Explore, FeaturedRooms, PublicRooms } from './client/explore';
|
||||||
import { setAfterLoginRedirectPath } from './afterLoginRedirectPath';
|
import { setAfterLoginRedirectPath } from './afterLoginRedirectPath';
|
||||||
|
|
@ -302,7 +297,7 @@ export const createRouter = (clientConfig: ClientConfig, screenSize: ScreenSize)
|
||||||
</MobileFriendlyPageNav>
|
</MobileFriendlyPageNav>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<ChannelsLanding />
|
{mobile ? null : <WelcomePage />}
|
||||||
</PageRoot>
|
</PageRoot>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -4,24 +4,31 @@ import { PageNav, PageNavContent } from '../../../components/page';
|
||||||
import { StreamHeader } from '../../../components/stream-header';
|
import { StreamHeader } from '../../../components/stream-header';
|
||||||
import { ChannelsList } from './ChannelsList';
|
import { ChannelsList } from './ChannelsList';
|
||||||
import { ChannelCreateRow } from './ChannelCreateRow';
|
import { ChannelCreateRow } from './ChannelCreateRow';
|
||||||
|
import { ChannelsLanding } from './ChannelsLanding';
|
||||||
import { ChannelsWorkspaceHorseshoe } from './ChannelsWorkspaceHorseshoe';
|
import { ChannelsWorkspaceHorseshoe } from './ChannelsWorkspaceHorseshoe';
|
||||||
import { WorkspaceFooter } from './WorkspaceFooter';
|
import { WorkspaceFooter } from './WorkspaceFooter';
|
||||||
import { ACTIVE_SPACE_KEY } from './useActiveSpace';
|
import { ACTIVE_SPACE_KEY } from './useActiveSpace';
|
||||||
|
|
||||||
// Index route at /channels/ (no space selected). Renders the shared
|
// Index route at /channels/ (no space selected). Renders the shared
|
||||||
// StreamHeader so the segment switcher is consistent across surfaces,
|
// StreamHeader (segment switcher) plus the resolve-active-space-or-
|
||||||
// but no list/footer — those need a Space context.
|
// 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() {
|
export function ChannelsRootNav() {
|
||||||
const scrollRef = useRef<HTMLDivElement>(null);
|
const scrollRef = useRef<HTMLDivElement>(null);
|
||||||
return (
|
return (
|
||||||
<PageNav resizable surface="surfaceVariant">
|
<PageNav resizable surface="surfaceVariant">
|
||||||
<StreamHeader scrollRef={scrollRef}>
|
<StreamHeader scrollRef={scrollRef}>
|
||||||
<PageNavContent scrollRef={scrollRef}>
|
<ChannelsLanding />
|
||||||
{/* 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>
|
|
||||||
</StreamHeader>
|
</StreamHeader>
|
||||||
</PageNav>
|
</PageNav>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { Box, Button, Icon, Icons, Text } from 'folds';
|
||||||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||||
import { allRoomsAtom } from '../../../state/room-list/roomList';
|
import { allRoomsAtom } from '../../../state/room-list/roomList';
|
||||||
import { useOrphanSpaces } from '../../../state/hooks/roomList';
|
import { useOrphanSpaces } from '../../../state/hooks/roomList';
|
||||||
|
import { useOpenCreateSpaceModal } from '../../../state/hooks/createSpaceModal';
|
||||||
import { roomToParentsAtom } from '../../../state/room/roomToParents';
|
import { roomToParentsAtom } from '../../../state/room/roomToParents';
|
||||||
import { getCanonicalAliasOrRoomId } from '../../../utils/matrix';
|
import { getCanonicalAliasOrRoomId } from '../../../utils/matrix';
|
||||||
import { getChannelsSpacePath, getExplorePath } from '../../pathUtils';
|
import { getChannelsSpacePath, getExplorePath } from '../../pathUtils';
|
||||||
|
|
@ -19,6 +20,7 @@ export function ChannelsLanding() {
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const openCreateSpaceModal = useOpenCreateSpaceModal();
|
||||||
const roomToParents = useAtomValue(roomToParentsAtom);
|
const roomToParents = useAtomValue(roomToParentsAtom);
|
||||||
const orphanSpaces = useOrphanSpaces(mx, allRoomsAtom, roomToParents);
|
const orphanSpaces = useOrphanSpaces(mx, allRoomsAtom, roomToParents);
|
||||||
const activeSpaceId = useActiveSpace(orphanSpaces);
|
const activeSpaceId = useActiveSpace(orphanSpaces);
|
||||||
|
|
@ -49,6 +51,16 @@ export function ChannelsLanding() {
|
||||||
{t('Channels.explore_cta')}
|
{t('Channels.explore_cta')}
|
||||||
</Text>
|
</Text>
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="Secondary"
|
||||||
|
fill="Soft"
|
||||||
|
size="300"
|
||||||
|
onClick={() => openCreateSpaceModal()}
|
||||||
|
>
|
||||||
|
<Text size="B300" truncate>
|
||||||
|
{t('Channels.workspace_switcher_create_space')}
|
||||||
|
</Text>
|
||||||
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
export * from './Channels';
|
export * from './Channels';
|
||||||
export * from './ChannelsList';
|
export * from './ChannelsList';
|
||||||
export * from './ChannelsLanding';
|
|
||||||
export * from './ChannelPickPlaceholder';
|
export * from './ChannelPickPlaceholder';
|
||||||
export * from './useActiveSpace';
|
export * from './useActiveSpace';
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue