From 7ea273eca8e9268a66f826025531b3bf83b3ef98 Mon Sep 17 00:00:00 2001 From: heaven Date: Thu, 4 Jun 2026 00:59:55 +0300 Subject: [PATCH] style(create-chat): Dawn grouped form with a mono server and one native layout without the hero --- .../stream-header/forms/InlineNewChatForm.tsx | 10 +- src/app/features/create-chat/CreateChat.tsx | 98 ++++++++----------- src/app/pages/client/direct/DirectCreate.tsx | 86 +++++----------- 3 files changed, 70 insertions(+), 124 deletions(-) diff --git a/src/app/components/stream-header/forms/InlineNewChatForm.tsx b/src/app/components/stream-header/forms/InlineNewChatForm.tsx index 80110f6c..16f1abd0 100644 --- a/src/app/components/stream-header/forms/InlineNewChatForm.tsx +++ b/src/app/components/stream-header/forms/InlineNewChatForm.tsx @@ -8,11 +8,11 @@ type Props = { onClose: () => void; }; -// Thin shell around the shared `CreateChat` form. The legacy -// `/direct/_create` route renders the same component with a Page/ -// PageHero shell; here we only feed it the `onClose` callback and the -// tighter `gap='400'` rhythm so the form fits comfortably under the -// header. +// Thin shell around the shared `CreateChat` form. This curtain is the +// canonical native new-chat surface; the `/direct/_create` route renders +// the same grouped block under a back-chevron PageHeader. Here we only +// feed it the `onClose` callback and the tighter `gap='400'` rhythm so the +// form fits comfortably under the header. export function InlineNewChatForm({ onClose }: Props) { return ; } diff --git a/src/app/features/create-chat/CreateChat.tsx b/src/app/features/create-chat/CreateChat.tsx index dcfe3d1a..10f4c916 100644 --- a/src/app/features/create-chat/CreateChat.tsx +++ b/src/app/features/create-chat/CreateChat.tsx @@ -1,22 +1,11 @@ -import { - Box, - Button, - color, - config, - Icon, - Icons, - Input, - Spinner, - Switch, - Text, - toRem, -} from 'folds'; +import { Box, Button, color, Icon, Icons, Input, Spinner, Switch, Text, toRem } from 'folds'; import React, { FormEventHandler, useCallback, useState } from 'react'; import { useTranslation } from 'react-i18next'; 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 { SettingsSection } from '../settings/SettingsSection'; +import { Mono, SectionLabel } from '../settings/styles.css'; import { addRoomIdToMDirect, getDMRoomFor, @@ -136,17 +125,25 @@ export function CreateChat({ defaultUserId, onCreated, gap = '500' }: CreateChat return ( - + + + {t('Direct.address')} + - {t('Direct.username')} + @ + + } required autoFocus autoComplete="off" @@ -154,16 +151,17 @@ export function CreateChat({ defaultUserId, onCreated, gap = '500' }: CreateChat /> - {t('Direct.server')} @@ -171,50 +169,40 @@ export function CreateChat({ defaultUserId, onCreated, gap = '500' }: CreateChat {invalidUserId && ( - + - {t('Direct.invalid_user_id')} + {t('Direct.invalid_user_id')} )} - - {t('Direct.options')} - - - } - /> - - + + + } + /> + {error && ( - + - - {(() => { - if (error instanceof MatrixError && error.name === ErrorCode.M_LIMIT_EXCEEDED) { - const ra = error.data?.retry_after_ms; - return t('Direct.rate_limited', { - minutes: millisecondsToMinutes(typeof ra === 'number' ? ra : 0), - }); - } - return error.message; - })()} - + {(() => { + if (error instanceof MatrixError && error.name === ErrorCode.M_LIMIT_EXCEEDED) { + const ra = error.data?.retry_after_ms; + return t('Direct.rate_limited', { + minutes: millisecondsToMinutes(typeof ra === 'number' ? ra : 0), + }); + } + return error.message; + })()} )} diff --git a/src/app/pages/client/direct/DirectCreate.tsx b/src/app/pages/client/direct/DirectCreate.tsx index 1d367bfe..60a02454 100644 --- a/src/app/pages/client/direct/DirectCreate.tsx +++ b/src/app/pages/client/direct/DirectCreate.tsx @@ -7,24 +7,13 @@ import { getDirectCreateSearchParams } from '../../pathSearchParam'; import { getDirectRoomPath } from '../../pathUtils'; import { getDMRoomFor } from '../../../utils/matrix'; import { useDirectRooms } from './useDirectRooms'; -import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; -import { - Page, - PageContent, - PageContentCenter, - PageHeader, - PageHero, - PageHeroSection, -} from '../../../components/page'; +import { Page, PageContent, PageContentCenter, PageHeader } from '../../../components/page'; import { BackRouteHandler } from '../../../components/BackRouteHandler'; import { CreateChat } from '../../../features/create-chat'; -import { isNativePlatform } from '../../../utils/capacitor'; export function DirectCreate() { const { t } = useTranslation(); const mx = useMatrixClient(); - const screenSize = useScreenSizeContext(); - const native = isNativePlatform(); const navigate = useNavigate(); const [searchParams] = useSearchParams(); @@ -41,64 +30,33 @@ export function DirectCreate() { } }, [mx, navigate, directs, userId]); - // Native phone (Capacitor + Mobile screen): compact layout — title goes into - // the back-arrow header, form sits directly below with light padding, no - // oversized hero whitespace. The on-screen keyboard otherwise pushed the - // centered hero layout into a visibly long scrollable area. Native tablets, - // desktop, and web (any size) keep the original hero-section layout. - if (native && screenSize === ScreenSize.Mobile) { - return ( - - - - - {(onBack) => ( - - - - )} - - - {t('Direct.create_chat')} - - - - - - - - - - - - ); - } - + // One Dawn layout for every size: a left-aligned back-chevron header over the + // grouped CreateChat block in a padded Scroll. No centered hero — the curtain + // (InlineNewChatForm) is the canonical native new-chat surface, and the + // keyboard no longer fights an oversized hero on short native viewports. return ( - {screenSize === ScreenSize.Mobile && ( - - - - {(onBack) => ( - - - - )} - - - - )} + + + + {(onBack) => ( + + + + )} + + + {t('Direct.create_chat')} + + + - - - - - - + + +