mirror of
				https://github.com/cinnyapp/cinny.git
				synced 2025-11-04 14:30:29 +03:00 
			
		
		
		
	add new create chat screen
This commit is contained in:
		
							parent
							
								
									dfd9809ddd
								
							
						
					
					
						commit
						492b3e17a4
					
				
					 6 changed files with 228 additions and 58 deletions
				
			
		| 
						 | 
				
			
			@ -1,7 +1,8 @@
 | 
			
		|||
import { Box, Button, color, config, Icon, Icons, Spinner, Text } from 'folds';
 | 
			
		||||
import React, { useCallback } from 'react';
 | 
			
		||||
import { Box, Button, config, Icon, Icons, Text } from 'folds';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { useNavigate } from 'react-router-dom';
 | 
			
		||||
import { UserHero, UserHeroName } from './UserHero';
 | 
			
		||||
import { getDMRoomFor, getMxIdServer, mxcUrlToHttp } from '../../utils/matrix';
 | 
			
		||||
import { getMxIdServer, mxcUrlToHttp } from '../../utils/matrix';
 | 
			
		||||
import { getMemberAvatarMxc, getMemberDisplayName } from '../../utils/room';
 | 
			
		||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
 | 
			
		||||
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
 | 
			
		||||
| 
						 | 
				
			
			@ -9,11 +10,6 @@ import { usePowerLevels } from '../../hooks/usePowerLevels';
 | 
			
		|||
import { useRoom } from '../../hooks/useRoom';
 | 
			
		||||
import { useUserPresence } from '../../hooks/useUserPresence';
 | 
			
		||||
import { IgnoredUserAlert, MutualRoomsChip, OptionsChip, ServerChip, ShareChip } from './UserChips';
 | 
			
		||||
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
 | 
			
		||||
import { createDM } from '../../../client/action/room';
 | 
			
		||||
import { hasDevices } from '../../../util/matrixUtil';
 | 
			
		||||
import { useRoomNavigate } from '../../hooks/useRoomNavigate';
 | 
			
		||||
import { useAlive } from '../../hooks/useAlive';
 | 
			
		||||
import { useCloseUserRoomProfile } from '../../state/hooks/userRoomProfile';
 | 
			
		||||
import { PowerChip } from './PowerChip';
 | 
			
		||||
import { UserInviteAlert, UserBanAlert, UserModeration, UserKickAlert } from './UserModeration';
 | 
			
		||||
| 
						 | 
				
			
			@ -24,6 +20,8 @@ import { useRoomCreators } from '../../hooks/useRoomCreators';
 | 
			
		|||
import { useRoomPermissions } from '../../hooks/useRoomPermissions';
 | 
			
		||||
import { useMemberPowerCompare } from '../../hooks/useMemberPowerCompare';
 | 
			
		||||
import { CreatorChip } from './CreatorChip';
 | 
			
		||||
import { getDirectCreatePath, withSearchParam } from '../../pages/pathUtils';
 | 
			
		||||
import { DirectCreateSearchParams } from '../../pages/paths';
 | 
			
		||||
 | 
			
		||||
type UserRoomProfileProps = {
 | 
			
		||||
  userId: string;
 | 
			
		||||
| 
						 | 
				
			
			@ -31,8 +29,7 @@ type UserRoomProfileProps = {
 | 
			
		|||
export function UserRoomProfile({ userId }: UserRoomProfileProps) {
 | 
			
		||||
  const mx = useMatrixClient();
 | 
			
		||||
  const useAuthentication = useMediaAuthentication();
 | 
			
		||||
  const { navigateRoom } = useRoomNavigate();
 | 
			
		||||
  const alive = useAlive();
 | 
			
		||||
  const navigate = useNavigate();
 | 
			
		||||
  const closeUserRoomProfile = useCloseUserRoomProfile();
 | 
			
		||||
  const ignoredUsers = useIgnoredUsers();
 | 
			
		||||
  const ignored = ignoredUsers.includes(userId);
 | 
			
		||||
| 
						 | 
				
			
			@ -62,26 +59,12 @@ export function UserRoomProfile({ userId }: UserRoomProfileProps) {
 | 
			
		|||
 | 
			
		||||
  const presence = useUserPresence(userId);
 | 
			
		||||
 | 
			
		||||
  const [directMessageState, directMessage] = useAsyncCallback<string, Error, []>(
 | 
			
		||||
    useCallback(async () => {
 | 
			
		||||
      const result = await createDM(mx, userId, await hasDevices(mx, userId));
 | 
			
		||||
      return result.room_id as string;
 | 
			
		||||
    }, [userId, mx])
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const handleMessage = () => {
 | 
			
		||||
    const dmRoomId = getDMRoomFor(mx, userId)?.roomId;
 | 
			
		||||
    if (dmRoomId) {
 | 
			
		||||
      navigateRoom(dmRoomId);
 | 
			
		||||
      closeUserRoomProfile();
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    directMessage().then((rId) => {
 | 
			
		||||
      if (alive()) {
 | 
			
		||||
        navigateRoom(rId);
 | 
			
		||||
        closeUserRoomProfile();
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    closeUserRoomProfile();
 | 
			
		||||
    const directSearchParam: DirectCreateSearchParams = {
 | 
			
		||||
      userId,
 | 
			
		||||
    };
 | 
			
		||||
    navigate(withSearchParam(getDirectCreatePath(), directSearchParam));
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
| 
						 | 
				
			
			@ -101,25 +84,13 @@ export function UserRoomProfile({ userId }: UserRoomProfileProps) {
 | 
			
		|||
                variant="Primary"
 | 
			
		||||
                fill="Solid"
 | 
			
		||||
                radii="300"
 | 
			
		||||
                disabled={directMessageState.status === AsyncStatus.Loading}
 | 
			
		||||
                before={
 | 
			
		||||
                  directMessageState.status === AsyncStatus.Loading ? (
 | 
			
		||||
                    <Spinner size="50" variant="Primary" fill="Solid" />
 | 
			
		||||
                  ) : (
 | 
			
		||||
                    <Icon size="50" src={Icons.Message} filled />
 | 
			
		||||
                  )
 | 
			
		||||
                }
 | 
			
		||||
                before={<Icon size="50" src={Icons.Message} filled />}
 | 
			
		||||
                onClick={handleMessage}
 | 
			
		||||
              >
 | 
			
		||||
                <Text size="B300">Message</Text>
 | 
			
		||||
              </Button>
 | 
			
		||||
            </Box>
 | 
			
		||||
          </Box>
 | 
			
		||||
          {directMessageState.status === AsyncStatus.Error && (
 | 
			
		||||
            <Text style={{ color: color.Critical.Main }}>
 | 
			
		||||
              <b>{directMessageState.error.message}</b>
 | 
			
		||||
            </Text>
 | 
			
		||||
          )}
 | 
			
		||||
          <Box alignItems="Center" gap="200" wrap="Wrap">
 | 
			
		||||
            {server && <ServerChip server={server} />}
 | 
			
		||||
            <ShareChip userId={userId} />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										150
									
								
								src/app/features/create-chat/CreateChat.tsx
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								src/app/features/create-chat/CreateChat.tsx
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,150 @@
 | 
			
		|||
import { Box, Button, color, config, Icon, Icons, Input, Spinner, Switch, Text } from 'folds';
 | 
			
		||||
import React, { FormEventHandler, useCallback, useState } from 'react';
 | 
			
		||||
import { ICreateRoomStateEvent, MatrixError, Preset, Visibility } from 'matrix-js-sdk';
 | 
			
		||||
import { useNavigate } from 'react-router-dom';
 | 
			
		||||
import { SettingTile } from '../../components/setting-tile';
 | 
			
		||||
import { SequenceCard } from '../../components/sequence-card';
 | 
			
		||||
import { addRoomIdToMDirect, isUserId } from '../../utils/matrix';
 | 
			
		||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
 | 
			
		||||
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
 | 
			
		||||
import { ErrorCode } from '../../cs-errorcode';
 | 
			
		||||
import { millisecondsToMinutes } from '../../utils/common';
 | 
			
		||||
import { createRoomEncryptionState } from '../../components/create-room';
 | 
			
		||||
import { useAlive } from '../../hooks/useAlive';
 | 
			
		||||
import { getDirectRoomPath } from '../../pages/pathUtils';
 | 
			
		||||
 | 
			
		||||
type CreateChatProps = {
 | 
			
		||||
  defaultUserId?: string;
 | 
			
		||||
};
 | 
			
		||||
export function CreateChat({ defaultUserId }: CreateChatProps) {
 | 
			
		||||
  const mx = useMatrixClient();
 | 
			
		||||
  const alive = useAlive();
 | 
			
		||||
  const navigate = useNavigate();
 | 
			
		||||
 | 
			
		||||
  const [encryption, setEncryption] = useState(true);
 | 
			
		||||
  const [invalidUserId, setInvalidUserId] = useState(false);
 | 
			
		||||
 | 
			
		||||
  const [createState, create] = useAsyncCallback<string, Error | MatrixError, [string, boolean]>(
 | 
			
		||||
    useCallback(
 | 
			
		||||
      async (userId, encrypted) => {
 | 
			
		||||
        const initialState: ICreateRoomStateEvent[] = [];
 | 
			
		||||
 | 
			
		||||
        if (encrypted) initialState.push(createRoomEncryptionState());
 | 
			
		||||
 | 
			
		||||
        const result = await mx.createRoom({
 | 
			
		||||
          is_direct: true,
 | 
			
		||||
          invite: [userId],
 | 
			
		||||
          visibility: Visibility.Private,
 | 
			
		||||
          preset: Preset.TrustedPrivateChat,
 | 
			
		||||
          initial_state: initialState,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        addRoomIdToMDirect(mx, result.room_id, userId);
 | 
			
		||||
 | 
			
		||||
        return result.room_id;
 | 
			
		||||
      },
 | 
			
		||||
      [mx]
 | 
			
		||||
    )
 | 
			
		||||
  );
 | 
			
		||||
  const loading = createState.status === AsyncStatus.Loading;
 | 
			
		||||
  const error = createState.status === AsyncStatus.Error ? createState.error : undefined;
 | 
			
		||||
  const disabled = createState.status === AsyncStatus.Loading;
 | 
			
		||||
 | 
			
		||||
  const handleSubmit: FormEventHandler<HTMLFormElement> = (evt) => {
 | 
			
		||||
    evt.preventDefault();
 | 
			
		||||
    setInvalidUserId(false);
 | 
			
		||||
 | 
			
		||||
    const target = evt.target as HTMLFormElement | undefined;
 | 
			
		||||
    const userIdInput = target?.userIdInput as HTMLInputElement | undefined;
 | 
			
		||||
    const userId = userIdInput?.value.trim();
 | 
			
		||||
 | 
			
		||||
    if (!userIdInput || !userId) return;
 | 
			
		||||
    if (!isUserId(userId)) {
 | 
			
		||||
      setInvalidUserId(true);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    create(userId, encryption).then((roomId) => {
 | 
			
		||||
      if (alive()) {
 | 
			
		||||
        userIdInput.value = '';
 | 
			
		||||
        navigate(getDirectRoomPath(roomId));
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <Box as="form" onSubmit={handleSubmit} grow="Yes" direction="Column" gap="500">
 | 
			
		||||
      <Box direction="Column" gap="100">
 | 
			
		||||
        <Text size="L400">User ID</Text>
 | 
			
		||||
        <Input
 | 
			
		||||
          defaultValue={defaultUserId}
 | 
			
		||||
          placeholder="@john:server"
 | 
			
		||||
          name="userIdInput"
 | 
			
		||||
          variant="SurfaceVariant"
 | 
			
		||||
          size="500"
 | 
			
		||||
          radii="400"
 | 
			
		||||
          required
 | 
			
		||||
          autoFocus
 | 
			
		||||
          autoComplete="off"
 | 
			
		||||
          disabled={disabled}
 | 
			
		||||
        />
 | 
			
		||||
        {invalidUserId && (
 | 
			
		||||
          <Box style={{ color: color.Critical.Main }} alignItems="Center" gap="100">
 | 
			
		||||
            <Icon src={Icons.Warning} filled size="50" />
 | 
			
		||||
            <Text size="T200" style={{ color: color.Critical.Main }}>
 | 
			
		||||
              <b>Please enter a valid User ID.</b>
 | 
			
		||||
            </Text>
 | 
			
		||||
          </Box>
 | 
			
		||||
        )}
 | 
			
		||||
      </Box>
 | 
			
		||||
      <Box shrink="No" direction="Column" gap="100">
 | 
			
		||||
        <Text size="L400">Options</Text>
 | 
			
		||||
        <SequenceCard
 | 
			
		||||
          style={{ padding: config.space.S300 }}
 | 
			
		||||
          variant="SurfaceVariant"
 | 
			
		||||
          direction="Column"
 | 
			
		||||
          gap="500"
 | 
			
		||||
        >
 | 
			
		||||
          <SettingTile
 | 
			
		||||
            title="End-to-End Encryption"
 | 
			
		||||
            description="Once this feature is enabled, it can't be disabled after the room is created."
 | 
			
		||||
            after={
 | 
			
		||||
              <Switch
 | 
			
		||||
                variant="Primary"
 | 
			
		||||
                value={encryption}
 | 
			
		||||
                onChange={setEncryption}
 | 
			
		||||
                disabled={disabled}
 | 
			
		||||
              />
 | 
			
		||||
            }
 | 
			
		||||
          />
 | 
			
		||||
        </SequenceCard>
 | 
			
		||||
      </Box>
 | 
			
		||||
      {error && (
 | 
			
		||||
        <Box style={{ color: color.Critical.Main }} alignItems="Center" gap="200">
 | 
			
		||||
          <Icon src={Icons.Warning} filled size="100" />
 | 
			
		||||
          <Text size="T300" style={{ color: color.Critical.Main }}>
 | 
			
		||||
            <b>
 | 
			
		||||
              {error instanceof MatrixError && error.name === ErrorCode.M_LIMIT_EXCEEDED
 | 
			
		||||
                ? `Server rate-limited your request for ${millisecondsToMinutes(
 | 
			
		||||
                    (error.data.retry_after_ms as number | undefined) ?? 0
 | 
			
		||||
                  )} minutes!`
 | 
			
		||||
                : error.message}
 | 
			
		||||
            </b>
 | 
			
		||||
          </Text>
 | 
			
		||||
        </Box>
 | 
			
		||||
      )}
 | 
			
		||||
      <Box shrink="No" direction="Column" gap="200">
 | 
			
		||||
        <Button
 | 
			
		||||
          type="submit"
 | 
			
		||||
          size="500"
 | 
			
		||||
          variant="Primary"
 | 
			
		||||
          radii="400"
 | 
			
		||||
          disabled={disabled}
 | 
			
		||||
          before={loading && <Spinner variant="Primary" fill="Solid" size="200" />}
 | 
			
		||||
        >
 | 
			
		||||
          <Text size="B500">Create</Text>
 | 
			
		||||
        </Button>
 | 
			
		||||
      </Box>
 | 
			
		||||
    </Box>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1
									
								
								src/app/features/create-chat/index.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/app/features/create-chat/index.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
export * from './CreateChat';
 | 
			
		||||
| 
						 | 
				
			
			@ -17,6 +17,7 @@ import {
 | 
			
		|||
} from 'folds';
 | 
			
		||||
import { useVirtualizer } from '@tanstack/react-virtual';
 | 
			
		||||
import FocusTrap from 'focus-trap-react';
 | 
			
		||||
import { useNavigate } from 'react-router-dom';
 | 
			
		||||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
 | 
			
		||||
import { factoryRoomIdByActivity } from '../../../utils/sort';
 | 
			
		||||
import {
 | 
			
		||||
| 
						 | 
				
			
			@ -28,7 +29,7 @@ import {
 | 
			
		|||
  NavItem,
 | 
			
		||||
  NavItemContent,
 | 
			
		||||
} from '../../../components/nav';
 | 
			
		||||
import { getDirectRoomPath } from '../../pathUtils';
 | 
			
		||||
import { getDirectCreatePath, getDirectRoomPath } from '../../pathUtils';
 | 
			
		||||
import { getCanonicalAliasOrRoomId } from '../../../utils/matrix';
 | 
			
		||||
import { useSelectedRoom } from '../../../hooks/router/useSelectedRoom';
 | 
			
		||||
import { VirtualTile } from '../../../components/virtualizer';
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +39,6 @@ import { roomToUnreadAtom } from '../../../state/room/roomToUnread';
 | 
			
		|||
import { useCategoryHandler } from '../../../hooks/useCategoryHandler';
 | 
			
		||||
import { useNavToActivePathMapper } from '../../../hooks/useNavToActivePathMapper';
 | 
			
		||||
import { useDirectRooms } from './useDirectRooms';
 | 
			
		||||
import { openInviteUser } from '../../../../client/action/navigation';
 | 
			
		||||
import { PageNav, PageNavContent, PageNavHeader } from '../../../components/page';
 | 
			
		||||
import { useClosedNavCategoriesAtom } from '../../../state/hooks/closedNavCategories';
 | 
			
		||||
import { useRoomsUnread } from '../../../state/hooks/unread';
 | 
			
		||||
| 
						 | 
				
			
			@ -50,6 +50,7 @@ import {
 | 
			
		|||
  getRoomNotificationMode,
 | 
			
		||||
  useRoomsNotificationPreferencesContext,
 | 
			
		||||
} from '../../../hooks/useRoomsNotificationPreferences';
 | 
			
		||||
import { useDirectCreateSelected } from '../../../hooks/router/useDirectSelected';
 | 
			
		||||
 | 
			
		||||
type DirectMenuProps = {
 | 
			
		||||
  requestClose: () => void;
 | 
			
		||||
| 
						 | 
				
			
			@ -138,6 +139,8 @@ function DirectHeader() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
function DirectEmpty() {
 | 
			
		||||
  const navigate = useNavigate();
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <NavEmptyCenter>
 | 
			
		||||
      <NavEmptyLayout
 | 
			
		||||
| 
						 | 
				
			
			@ -153,7 +156,7 @@ function DirectEmpty() {
 | 
			
		|||
          </Text>
 | 
			
		||||
        }
 | 
			
		||||
        options={
 | 
			
		||||
          <Button variant="Secondary" size="300" onClick={() => openInviteUser()}>
 | 
			
		||||
          <Button variant="Secondary" size="300" onClick={() => navigate(getDirectCreatePath())}>
 | 
			
		||||
            <Text size="B300" truncate>
 | 
			
		||||
              Direct Message
 | 
			
		||||
            </Text>
 | 
			
		||||
| 
						 | 
				
			
			@ -172,6 +175,9 @@ export function Direct() {
 | 
			
		|||
  const directs = useDirectRooms();
 | 
			
		||||
  const notificationPreferences = useRoomsNotificationPreferencesContext();
 | 
			
		||||
  const roomToUnread = useAtomValue(roomToUnreadAtom);
 | 
			
		||||
  const navigate = useNavigate();
 | 
			
		||||
 | 
			
		||||
  const createDirectSelected = useDirectCreateSelected();
 | 
			
		||||
 | 
			
		||||
  const selectedRoomId = useSelectedRoom();
 | 
			
		||||
  const noRoomToDisplay = directs.length === 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -205,8 +211,8 @@ export function Direct() {
 | 
			
		|||
        <PageNavContent scrollRef={scrollRef}>
 | 
			
		||||
          <Box direction="Column" gap="300">
 | 
			
		||||
            <NavCategory>
 | 
			
		||||
              <NavItem variant="Background" radii="400">
 | 
			
		||||
                <NavButton onClick={() => openInviteUser()}>
 | 
			
		||||
              <NavItem variant="Background" radii="400" aria-selected={createDirectSelected}>
 | 
			
		||||
                <NavButton onClick={() => navigate(getDirectCreatePath())}>
 | 
			
		||||
                  <NavItemContent>
 | 
			
		||||
                    <Box as="span" grow="Yes" alignItems="Center" gap="200">
 | 
			
		||||
                      <Avatar size="200" radii="400">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,33 +1,75 @@
 | 
			
		|||
import React, { useEffect } from 'react';
 | 
			
		||||
import { useNavigate, useSearchParams } from 'react-router-dom';
 | 
			
		||||
import { WelcomePage } from '../WelcomePage';
 | 
			
		||||
import { Box, Icon, IconButton, Icons, Scroll } from 'folds';
 | 
			
		||||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
 | 
			
		||||
import { getDirectCreateSearchParams } from '../../pathSearchParam';
 | 
			
		||||
import { getDirectPath, getDirectRoomPath } from '../../pathUtils';
 | 
			
		||||
import { getDirectRoomPath } from '../../pathUtils';
 | 
			
		||||
import { getDMRoomFor } from '../../../utils/matrix';
 | 
			
		||||
import { openInviteUser } from '../../../../client/action/navigation';
 | 
			
		||||
import { useDirectRooms } from './useDirectRooms';
 | 
			
		||||
import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize';
 | 
			
		||||
import {
 | 
			
		||||
  Page,
 | 
			
		||||
  PageContent,
 | 
			
		||||
  PageContentCenter,
 | 
			
		||||
  PageHeader,
 | 
			
		||||
  PageHero,
 | 
			
		||||
  PageHeroSection,
 | 
			
		||||
} from '../../../components/page';
 | 
			
		||||
import { BackRouteHandler } from '../../../components/BackRouteHandler';
 | 
			
		||||
import { CreateChat } from '../../../features/create-chat';
 | 
			
		||||
 | 
			
		||||
export function DirectCreate() {
 | 
			
		||||
  const mx = useMatrixClient();
 | 
			
		||||
  const screenSize = useScreenSizeContext();
 | 
			
		||||
 | 
			
		||||
  const navigate = useNavigate();
 | 
			
		||||
  const [searchParams] = useSearchParams();
 | 
			
		||||
  const { userId } = getDirectCreateSearchParams(searchParams);
 | 
			
		||||
 | 
			
		||||
  const directs = useDirectRooms();
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (userId) {
 | 
			
		||||
      const room = getDMRoomFor(mx, userId);
 | 
			
		||||
      const { roomId } = room ?? {};
 | 
			
		||||
      const roomId = getDMRoomFor(mx, userId)?.roomId;
 | 
			
		||||
      if (roomId && directs.includes(roomId)) {
 | 
			
		||||
        navigate(getDirectRoomPath(roomId), { replace: true });
 | 
			
		||||
      } else {
 | 
			
		||||
        openInviteUser(undefined, userId);
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      navigate(getDirectPath(), { replace: true });
 | 
			
		||||
    }
 | 
			
		||||
  }, [mx, navigate, directs, userId]);
 | 
			
		||||
 | 
			
		||||
  return <WelcomePage />;
 | 
			
		||||
  return (
 | 
			
		||||
    <Page>
 | 
			
		||||
      {screenSize === ScreenSize.Mobile && (
 | 
			
		||||
        <PageHeader balance outlined={false}>
 | 
			
		||||
          <Box grow="Yes" alignItems="Center" gap="200">
 | 
			
		||||
            <BackRouteHandler>
 | 
			
		||||
              {(onBack) => (
 | 
			
		||||
                <IconButton onClick={onBack}>
 | 
			
		||||
                  <Icon src={Icons.ArrowLeft} />
 | 
			
		||||
                </IconButton>
 | 
			
		||||
              )}
 | 
			
		||||
            </BackRouteHandler>
 | 
			
		||||
          </Box>
 | 
			
		||||
        </PageHeader>
 | 
			
		||||
      )}
 | 
			
		||||
      <Box grow="Yes">
 | 
			
		||||
        <Scroll hideTrack visibility="Hover">
 | 
			
		||||
          <PageContent>
 | 
			
		||||
            <PageContentCenter>
 | 
			
		||||
              <PageHeroSection>
 | 
			
		||||
                <Box direction="Column" gap="700">
 | 
			
		||||
                  <PageHero
 | 
			
		||||
                    icon={<Icon size="600" src={Icons.Mention} />}
 | 
			
		||||
                    title="Create Chat"
 | 
			
		||||
                    subTitle="Start a private, encrypted chat by entering a user ID."
 | 
			
		||||
                  />
 | 
			
		||||
                  <CreateChat defaultUserId={userId} />
 | 
			
		||||
                </Box>
 | 
			
		||||
              </PageHeroSection>
 | 
			
		||||
            </PageContentCenter>
 | 
			
		||||
          </PageContent>
 | 
			
		||||
        </Scroll>
 | 
			
		||||
      </Box>
 | 
			
		||||
    </Page>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,7 +42,7 @@ export function HomeCreateRoom() {
 | 
			
		|||
                  <PageHero
 | 
			
		||||
                    icon={<Icon size="600" src={Icons.Hash} />}
 | 
			
		||||
                    title="Create Room"
 | 
			
		||||
                    subTitle="Build a Room for Real-Time Conversations"
 | 
			
		||||
                    subTitle="Build a Room for Real-Time Conversations."
 | 
			
		||||
                  />
 | 
			
		||||
                  <CreateRoomForm onCreate={navigateRoom} />
 | 
			
		||||
                </Box>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue