@@ -1,11 +1,10 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import Stack from '@/components/ui/stack';
|
||||
import Text from '@/components/ui/text';
|
||||
|
||||
const Blankslate = () => (
|
||||
<Stack justifyContent='center' alignItems='center' space={2} className='mx-auto h-full w-2/3'>
|
||||
<div className='mx-auto flex h-full w-2/3 flex-col items-center justify-center gap-2'>
|
||||
<Text weight='bold' size='lg' align='center'>
|
||||
<FormattedMessage id='chat_search.blankslate.title' defaultMessage='Start a chat' />
|
||||
</Text>
|
||||
@@ -15,7 +14,7 @@ const Blankslate = () => (
|
||||
defaultMessage='Search for someone to chat with.'
|
||||
/>
|
||||
</Text>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
|
||||
export { Blankslate as default };
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
|
||||
import HStack from '@/components/ui/hstack';
|
||||
import Textarea from '@/components/ui/textarea';
|
||||
|
||||
import ChatPendingUpload from './chat-pending-upload';
|
||||
@@ -22,7 +21,7 @@ const ChatTextarea = React.forwardRef<HTMLTextAreaElement, IChatTextarea>(
|
||||
className={`block w-full rounded-md border border-gray-400 bg-white text-gray-900 shadow-sm placeholder:text-gray-600 focus-within:border-primary-500 focus-within:ring-1 focus-within:ring-primary-500 dark:border-gray-800 dark:bg-gray-800 dark:text-gray-100 dark:ring-1 dark:ring-gray-800 dark:placeholder:text-gray-600 dark:focus-within:border-primary-500 dark:focus-within:ring-primary-500 sm:text-sm`}
|
||||
>
|
||||
{(attachment ?? uploading) && (
|
||||
<HStack className='-ml-2 -mt-2 p-3 pb-0' wrap>
|
||||
<div className='-ml-2 -mt-2 flex flex-wrap p-3 pb-0'>
|
||||
{attachment && (
|
||||
<div className='ml-2 mt-2 flex'>
|
||||
<ChatUpload
|
||||
@@ -38,7 +37,7 @@ const ChatTextarea = React.forwardRef<HTMLTextAreaElement, IChatTextarea>(
|
||||
<ChatPendingUpload progress={uploadProgress} />
|
||||
</div>
|
||||
)}
|
||||
</HStack>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Textarea className='px-3 py-2' ref={ref} theme='transparent' {...rest} />
|
||||
|
||||
@@ -3,9 +3,7 @@ import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import Account from '@/components/accounts/account';
|
||||
import List, { ListItem } from '@/components/list';
|
||||
import HStack from '@/components/ui/hstack';
|
||||
import Icon from '@/components/ui/icon';
|
||||
import Stack from '@/components/ui/stack';
|
||||
import Text from '@/components/ui/text';
|
||||
import { ChatWidgetScreens, useChatContext } from '@/contexts/chat-context';
|
||||
import { useFeatures } from '@/hooks/use-features';
|
||||
@@ -102,7 +100,7 @@ const ChatSettings = () => {
|
||||
isToggleable={false}
|
||||
onToggle={minimizeChatPane}
|
||||
title={
|
||||
<HStack alignItems='center' space={2}>
|
||||
<div className='flex items-center gap-2'>
|
||||
<button onClick={closeSettings} title={intl.formatMessage(messages.back)}>
|
||||
<Icon
|
||||
src={require('@phosphor-icons/core/regular/arrow-left.svg')}
|
||||
@@ -113,11 +111,11 @@ const ChatSettings = () => {
|
||||
<Text weight='semibold'>
|
||||
<FormattedMessage id='chat_settings.title' defaultMessage='Chat details' />
|
||||
</Text>
|
||||
</HStack>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
|
||||
<Stack space={4} className='px-4'>
|
||||
<div className='flex flex-col gap-4 px-4'>
|
||||
<Account account={chat.account} hideActions />
|
||||
|
||||
<List>
|
||||
@@ -153,7 +151,7 @@ const ChatSettings = () => {
|
||||
/>
|
||||
)}
|
||||
</List>
|
||||
</Stack>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -4,9 +4,7 @@ import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import VerificationBadge from '@/components/accounts/verification-badge';
|
||||
import Avatar from '@/components/ui/avatar';
|
||||
import HStack from '@/components/ui/hstack';
|
||||
import Icon from '@/components/ui/icon';
|
||||
import Stack from '@/components/ui/stack';
|
||||
import Text from '@/components/ui/text';
|
||||
import { ChatWidgetScreens, useChatContext } from '@/contexts/chat-context';
|
||||
|
||||
@@ -63,7 +61,7 @@ const ChatWindow = () => {
|
||||
<>
|
||||
<ChatPaneHeader
|
||||
title={
|
||||
<HStack alignItems='center' space={2}>
|
||||
<div className='flex items-center gap-2'>
|
||||
{isOpen && (
|
||||
<button onClick={closeChat} title={intl.formatMessage(messages.back)}>
|
||||
<Icon
|
||||
@@ -73,7 +71,7 @@ const ChatWindow = () => {
|
||||
</button>
|
||||
)}
|
||||
|
||||
<HStack alignItems='center' space={3}>
|
||||
<div className='flex items-center gap-3'>
|
||||
{isOpen && (
|
||||
<Link to='/@{$username}' params={{ username: chat.account.acct }}>
|
||||
<Avatar
|
||||
@@ -86,7 +84,7 @@ const ChatWindow = () => {
|
||||
</Link>
|
||||
)}
|
||||
|
||||
<Stack alignItems='start'>
|
||||
<div className='flex flex-col items-start'>
|
||||
<LinkWrapper
|
||||
enabled={isOpen}
|
||||
to='/@{$username}'
|
||||
@@ -99,9 +97,9 @@ const ChatWindow = () => {
|
||||
{chat.account.verified && <VerificationBadge />}
|
||||
</div>
|
||||
</LinkWrapper>
|
||||
</Stack>
|
||||
</HStack>
|
||||
</HStack>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
secondaryAction={isOpen ? openChatSettings : openSearch}
|
||||
secondaryActionIcon={
|
||||
@@ -117,9 +115,9 @@ const ChatWindow = () => {
|
||||
onToggle={toggleChatPane}
|
||||
/>
|
||||
|
||||
<Stack className='h-full grow overflow-hidden' space={2}>
|
||||
<div className='flex h-full grow flex-col overflow-hidden'>
|
||||
<Chat chat={chat} inputRef={inputRef} />
|
||||
</Stack>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,9 +2,7 @@ import React from 'react';
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import Avatar from '@/components/ui/avatar';
|
||||
import HStack from '@/components/ui/hstack';
|
||||
import Icon from '@/components/ui/icon';
|
||||
import Stack from '@/components/ui/stack';
|
||||
import Text from '@/components/ui/text';
|
||||
import { ChatWidgetScreens, useChatContext } from '@/contexts/chat-context';
|
||||
import { useFrontendConfig } from '@/hooks/use-frontend-config';
|
||||
@@ -32,7 +30,7 @@ const ShoutboxWindow = () => {
|
||||
<>
|
||||
<ChatPaneHeader
|
||||
title={
|
||||
<HStack alignItems='center' space={2}>
|
||||
<div className='flex items-center gap-2'>
|
||||
{isOpen && (
|
||||
<button onClick={closeChat} title={intl.formatMessage(messages.back)}>
|
||||
<Icon
|
||||
@@ -42,10 +40,10 @@ const ShoutboxWindow = () => {
|
||||
</button>
|
||||
)}
|
||||
|
||||
<HStack alignItems='center' space={3}>
|
||||
<div className='flex items-center gap-3'>
|
||||
{isOpen && <Avatar src={logo} alt='' size={40} className='flex-none' />}
|
||||
|
||||
<Stack alignItems='start'>
|
||||
<div className='flex flex-col items-start'>
|
||||
<div className='flex grow items-center space-x-1'>
|
||||
<Text size='sm' weight='bold' truncate>
|
||||
<FormattedMessage
|
||||
@@ -55,18 +53,18 @@ const ShoutboxWindow = () => {
|
||||
/>
|
||||
</Text>
|
||||
</div>
|
||||
</Stack>
|
||||
</HStack>
|
||||
</HStack>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
isToggleable={!isOpen}
|
||||
isOpen={isOpen}
|
||||
onToggle={toggleChatPane}
|
||||
/>
|
||||
|
||||
<Stack className='h-full grow overflow-hidden' space={2}>
|
||||
<div className='flex h-full grow flex-col gap-2 overflow-hidden'>
|
||||
<Shoutbox />
|
||||
</Stack>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -3,7 +3,6 @@ import React, { type MutableRefObject, useEffect, useState } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import { uploadMedia } from '@/actions/media';
|
||||
import Stack from '@/components/ui/stack';
|
||||
import { useAppDispatch } from '@/hooks/use-app-dispatch';
|
||||
import { useCreateChatMessage } from '@/queries/chats';
|
||||
import toast from '@/toast';
|
||||
@@ -160,7 +159,7 @@ const Chat: React.FC<IChat> = ({ chat, inputRef, className }) => {
|
||||
}, [chat.id, inputRef?.current]);
|
||||
|
||||
return (
|
||||
<Stack className={clsx('flex grow overflow-hidden', className)}>
|
||||
<div className={clsx('flex grow flex-col overflow-hidden', className)}>
|
||||
<div className='flex h-full grow justify-center overflow-hidden'>
|
||||
<ChatMessageList key={chat.id} chat={chat} />
|
||||
</div>
|
||||
@@ -181,7 +180,7 @@ const Chat: React.FC<IChat> = ({ chat, inputRef, className }) => {
|
||||
uploading={uploading}
|
||||
uploadProgress={uploadProgress}
|
||||
/>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import { Outlet, useMatch } from '@tanstack/react-router';
|
||||
import clsx from 'clsx';
|
||||
import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||
|
||||
import Stack from '@/components/ui/stack';
|
||||
import { chatsEmptyRoute } from '@/features/ui/router';
|
||||
import { useChats } from '@/queries/chats';
|
||||
import { useShoutboxIsLoading } from '@/stores/shoutbox';
|
||||
@@ -58,24 +57,24 @@ const ChatsPage: React.FC = () => {
|
||||
className='grid h-full grid-cols-9 overflow-hidden black:divide-gray-800 dark:divide-solid dark:divide-primary-800 sm:black:divide-x sm:dark:divide-x-2'
|
||||
data-testid='chat-page'
|
||||
>
|
||||
<Stack
|
||||
<div
|
||||
className={clsx(
|
||||
'dark:inset col-span-9 overflow-hidden bg-gradient-to-r from-white to-gray-100 black:bg-black dark:bg-gray-900 dark:bg-none sm:col-span-3',
|
||||
'dark:inset col-span-9 flex flex-col overflow-hidden bg-gradient-to-r from-white to-gray-100 black:bg-black dark:bg-gray-900 dark:bg-none sm:col-span-3',
|
||||
{
|
||||
'hidden sm:block': isSidebarHidden,
|
||||
},
|
||||
)}
|
||||
>
|
||||
<ChatsPageSidebar />
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
<Stack
|
||||
className={clsx('col-span-9 h-full overflow-hidden sm:col-span-6', {
|
||||
<div
|
||||
className={clsx('col-span-9 flex h-full flex-col overflow-hidden sm:col-span-6', {
|
||||
'hidden sm:block': !isSidebarHidden,
|
||||
})}
|
||||
>
|
||||
<Outlet />
|
||||
</Stack>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -2,13 +2,12 @@ import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import Button from '@/components/ui/button';
|
||||
import Stack from '@/components/ui/stack';
|
||||
import Text from '@/components/ui/text';
|
||||
|
||||
/** To display on the chats main page when no message is selected. */
|
||||
const BlankslateEmpty: React.FC = () => (
|
||||
<Stack space={6} alignItems='center' justifyContent='center' className='h-full p-6'>
|
||||
<Stack space={2} className='max-w-sm'>
|
||||
<div className='flex h-full flex-col items-center justify-center gap-6 p-6'>
|
||||
<div className='flex max-w-sm flex-col gap-2'>
|
||||
<Text size='2xl' weight='bold' tag='h2' align='center'>
|
||||
<FormattedMessage id='chats.main.blankslate.title' defaultMessage='No messages yet' />
|
||||
</Text>
|
||||
@@ -19,12 +18,12 @@ const BlankslateEmpty: React.FC = () => (
|
||||
defaultMessage='Search for someone to chat with'
|
||||
/>
|
||||
</Text>
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
<Button theme='primary' to='/chats/new'>
|
||||
<FormattedMessage id='chats.main.blankslate.new_chat' defaultMessage='Message someone' />
|
||||
</Button>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
|
||||
export { BlankslateEmpty as default };
|
||||
|
||||
@@ -3,7 +3,6 @@ import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import Button from '@/components/ui/button';
|
||||
import Stack from '@/components/ui/stack';
|
||||
import Text from '@/components/ui/text';
|
||||
|
||||
/** To display on the chats main page when no message is selected, but chats are present. */
|
||||
@@ -15,8 +14,8 @@ const BlankslateWithChats = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack space={6} alignItems='center' justifyContent='center' className='h-full p-6'>
|
||||
<Stack space={2} className='max-w-sm'>
|
||||
<div className='flex h-full flex-col items-center justify-center gap-6 p-6'>
|
||||
<div className='flex max-w-sm flex-col gap-2'>
|
||||
<Text size='2xl' weight='bold' tag='h2' align='center'>
|
||||
<FormattedMessage
|
||||
id='chats.main.blankslate_with_chats.title'
|
||||
@@ -30,12 +29,12 @@ const BlankslateWithChats = () => {
|
||||
defaultMessage='Select from one of your open chats or create a new message.'
|
||||
/>
|
||||
</Text>
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
<Button theme='primary' onClick={handleNewChat}>
|
||||
<FormattedMessage id='chats.main.blankslate.new_chat' defaultMessage='Message someone' />
|
||||
</Button>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -6,9 +6,7 @@ import Account from '@/components/accounts/account';
|
||||
import VerificationBadge from '@/components/accounts/verification-badge';
|
||||
import DropdownMenu, { type Menu } from '@/components/dropdown-menu';
|
||||
import Avatar from '@/components/ui/avatar';
|
||||
import HStack from '@/components/ui/hstack';
|
||||
import IconButton from '@/components/ui/icon-button';
|
||||
import Stack from '@/components/ui/stack';
|
||||
import Text from '@/components/ui/text';
|
||||
import { chatRoute } from '@/features/ui/router';
|
||||
import { useFeatures } from '@/hooks/use-features';
|
||||
@@ -122,10 +120,10 @@ const ChatsPageChat = () => {
|
||||
});
|
||||
|
||||
return (
|
||||
<Stack className='h-full overflow-hidden'>
|
||||
<HStack alignItems='center' justifyContent='between' space={2} className='w-full p-4'>
|
||||
<HStack alignItems='center' space={2}>
|
||||
<HStack alignItems='center'>
|
||||
<div className='flex h-full flex-col overflow-hidden'>
|
||||
<div className='flex w-full items-center justify-between gap-2 p-4'>
|
||||
<div className='flex items-center gap-2'>
|
||||
<div className='flex items-center'>
|
||||
<IconButton
|
||||
src={require('@phosphor-icons/core/regular/arrow-left.svg')}
|
||||
className='mr-2 size-7 sm:mr-0 sm:hidden rtl:rotate-180'
|
||||
@@ -143,9 +141,9 @@ const ChatsPageChat = () => {
|
||||
username={chat.account.username}
|
||||
/>
|
||||
</Link>
|
||||
</HStack>
|
||||
</div>
|
||||
|
||||
<Stack alignItems='start' className='h-11 overflow-hidden'>
|
||||
<div className='flex h-11 flex-col items-start overflow-hidden'>
|
||||
<div className='flex w-full grow items-center space-x-1'>
|
||||
<Link to='/@{$username}' params={{ username: chat.account.acct }}>
|
||||
<Text weight='bold' size='sm' align='left' truncate>
|
||||
@@ -154,8 +152,8 @@ const ChatsPageChat = () => {
|
||||
</Link>
|
||||
{chat.account.verified && <VerificationBadge />}
|
||||
</div>
|
||||
</Stack>
|
||||
</HStack>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DropdownMenu
|
||||
src={require('@phosphor-icons/core/regular/info.svg')}
|
||||
@@ -166,12 +164,12 @@ const ChatsPageChat = () => {
|
||||
)}
|
||||
items={menuItems}
|
||||
/>
|
||||
</HStack>
|
||||
</div>
|
||||
|
||||
<div className='h-full overflow-hidden'>
|
||||
<Chat className='h-full' chat={chat} inputRef={inputRef} />
|
||||
</div>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -3,9 +3,7 @@ import React from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import { CardTitle } from '@/components/ui/card';
|
||||
import HStack from '@/components/ui/hstack';
|
||||
import IconButton from '@/components/ui/icon-button';
|
||||
import Stack from '@/components/ui/stack';
|
||||
|
||||
import ChatSearch from '../../chat-search/chat-search';
|
||||
|
||||
@@ -20,22 +18,20 @@ const ChatsPageNew: React.FC = () => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<Stack className='h-full gap-4'>
|
||||
<Stack className='grow px-4 pt-6 sm:px-6'>
|
||||
<HStack alignItems='center'>
|
||||
<IconButton
|
||||
src={require('@phosphor-icons/core/regular/arrow-left.svg')}
|
||||
className='mr-2 size-7 sm:mr-0 sm:hidden rtl:rotate-180'
|
||||
onClick={() => navigate({ to: '/chats' })}
|
||||
title={intl.formatMessage(messages.back)}
|
||||
/>
|
||||
<div className='flex h-full flex-col gap-4'>
|
||||
<div className='flex items-center px-4 pt-6 sm:px-6'>
|
||||
<IconButton
|
||||
src={require('@phosphor-icons/core/regular/arrow-left.svg')}
|
||||
className='mr-2 size-7 sm:mr-0 sm:hidden rtl:rotate-180'
|
||||
onClick={() => navigate({ to: '/chats' })}
|
||||
title={intl.formatMessage(messages.back)}
|
||||
/>
|
||||
|
||||
<CardTitle title={intl.formatMessage(messages.title)} />
|
||||
</HStack>
|
||||
</Stack>
|
||||
<CardTitle title={intl.formatMessage(messages.title)} />
|
||||
</div>
|
||||
|
||||
<ChatSearch isMainPage />
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -7,9 +7,7 @@ import List, { ListItem } from '@/components/list';
|
||||
import Button from '@/components/ui/button';
|
||||
import { CardBody, CardTitle } from '@/components/ui/card';
|
||||
import Form from '@/components/ui/form';
|
||||
import HStack from '@/components/ui/hstack';
|
||||
import IconButton from '@/components/ui/icon-button';
|
||||
import Stack from '@/components/ui/stack';
|
||||
import Toggle from '@/components/ui/toggle';
|
||||
import SettingToggle from '@/features/settings/components/setting-toggle';
|
||||
import { useAppDispatch } from '@/hooks/use-app-dispatch';
|
||||
@@ -73,8 +71,8 @@ const ChatsPageSettings = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack className='h-full space-y-8 px-4 py-6 sm:p-6'>
|
||||
<HStack alignItems='center'>
|
||||
<div className='flex h-full flex-col space-y-8 px-4 py-6 sm:p-6'>
|
||||
<div className='flex items-center'>
|
||||
<IconButton
|
||||
src={require('@phosphor-icons/core/regular/arrow-left.svg')}
|
||||
className='mr-2 size-7 sm:mr-0 sm:hidden rtl:rotate-180'
|
||||
@@ -83,7 +81,7 @@ const ChatsPageSettings = () => {
|
||||
/>
|
||||
|
||||
<CardTitle title={intl.formatMessage(messages.title)} />
|
||||
</HStack>
|
||||
</div>
|
||||
|
||||
<Form onSubmit={handleSubmit}>
|
||||
<CardTitle title={intl.formatMessage(messages.preferences)} />
|
||||
@@ -120,7 +118,7 @@ const ChatsPageSettings = () => {
|
||||
{intl.formatMessage(messages.submit)}
|
||||
</Button>
|
||||
</Form>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -3,9 +3,7 @@ import React from 'react';
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import Avatar from '@/components/ui/avatar';
|
||||
import HStack from '@/components/ui/hstack';
|
||||
import IconButton from '@/components/ui/icon-button';
|
||||
import Stack from '@/components/ui/stack';
|
||||
import Text from '@/components/ui/text';
|
||||
import { useFrontendConfig } from '@/hooks/use-frontend-config';
|
||||
import { useInstance } from '@/hooks/use-instance';
|
||||
@@ -23,38 +21,36 @@ const ChatsPageShoutbox = () => {
|
||||
const { logo } = useFrontendConfig();
|
||||
|
||||
return (
|
||||
<Stack className='h-full overflow-hidden'>
|
||||
<HStack alignItems='center' justifyContent='between' space={2} className='w-full p-4'>
|
||||
<HStack alignItems='center' space={2} className='overflow-hidden'>
|
||||
<HStack alignItems='center'>
|
||||
<IconButton
|
||||
src={require('@phosphor-icons/core/regular/arrow-left.svg')}
|
||||
className='mr-2 size-7 sm:mr-0 sm:hidden rtl:rotate-180'
|
||||
onClick={() => navigate({ to: '/chats' })}
|
||||
title={intl.formatMessage(messages.back)}
|
||||
/>
|
||||
<div className='flex h-full flex-col overflow-hidden'>
|
||||
<div className='flex w-full items-center gap-2 overflow-hidden p-4'>
|
||||
<div className='flex items-center'>
|
||||
<IconButton
|
||||
src={require('@phosphor-icons/core/regular/arrow-left.svg')}
|
||||
className='mr-2 size-7 sm:mr-0 sm:hidden rtl:rotate-180'
|
||||
onClick={() => navigate({ to: '/chats' })}
|
||||
title={intl.formatMessage(messages.back)}
|
||||
/>
|
||||
|
||||
<Avatar src={logo} alt='' size={40} className='flex-none' />
|
||||
</HStack>
|
||||
<Avatar src={logo} alt='' size={40} className='flex-none' />
|
||||
</div>
|
||||
|
||||
<Stack alignItems='start' className='h-11 overflow-hidden'>
|
||||
<div className='flex w-full grow items-center space-x-1'>
|
||||
<Text weight='bold' size='sm' align='left' truncate>
|
||||
<FormattedMessage
|
||||
id='chat_list_item_shoutbox'
|
||||
defaultMessage='{instance} shoutbox'
|
||||
values={{ instance: instance.title }}
|
||||
/>
|
||||
</Text>
|
||||
</div>
|
||||
</Stack>
|
||||
</HStack>
|
||||
</HStack>
|
||||
<div className='flex h-11 flex-col items-start overflow-hidden'>
|
||||
<div className='flex w-full grow items-center space-x-1'>
|
||||
<Text weight='bold' size='sm' align='left' truncate>
|
||||
<FormattedMessage
|
||||
id='chat_list_item_shoutbox'
|
||||
defaultMessage='{instance} shoutbox'
|
||||
values={{ instance: instance.title }}
|
||||
/>
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='h-full overflow-hidden'>
|
||||
<Shoutbox className='h-full' />
|
||||
</div>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -3,9 +3,7 @@ import React, { useCallback } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import { CardTitle } from '@/components/ui/card';
|
||||
import HStack from '@/components/ui/hstack';
|
||||
import IconButton from '@/components/ui/icon-button';
|
||||
import Stack from '@/components/ui/stack';
|
||||
|
||||
import ChatList from '../../chat-list';
|
||||
|
||||
@@ -41,33 +39,31 @@ const ChatsPageSidebar = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack space={4} className='h-full'>
|
||||
<Stack space={4} className='px-4 pt-6'>
|
||||
<HStack alignItems='center' justifyContent='between'>
|
||||
<CardTitle title={intl.formatMessage(messages.title)} />
|
||||
<div className='flex h-full flex-col gap-4'>
|
||||
<div className='flex items-center justify-between px-4 pt-6'>
|
||||
<CardTitle title={intl.formatMessage(messages.title)} />
|
||||
|
||||
<HStack space={1}>
|
||||
<IconButton
|
||||
src={require('@phosphor-icons/core/regular/sliders-horizontal.svg')}
|
||||
iconClassName='h-5 w-5 text-gray-600'
|
||||
onClick={handleSettingsClick}
|
||||
title={intl.formatMessage(messages.settings)}
|
||||
/>
|
||||
<div className='flex gap-1'>
|
||||
<IconButton
|
||||
src={require('@phosphor-icons/core/regular/sliders-horizontal.svg')}
|
||||
iconClassName='h-5 w-5 text-gray-600'
|
||||
onClick={handleSettingsClick}
|
||||
title={intl.formatMessage(messages.settings)}
|
||||
/>
|
||||
|
||||
<IconButton
|
||||
src={require('@phosphor-icons/core/regular/pencil-simple.svg')}
|
||||
iconClassName='h-5 w-5 text-gray-600'
|
||||
onClick={handleChatCreate}
|
||||
title={intl.formatMessage(messages.newChat)}
|
||||
/>
|
||||
</HStack>
|
||||
</HStack>
|
||||
</Stack>
|
||||
<IconButton
|
||||
src={require('@phosphor-icons/core/regular/pencil-simple.svg')}
|
||||
iconClassName='h-5 w-5 text-gray-600'
|
||||
onClick={handleChatCreate}
|
||||
title={intl.formatMessage(messages.newChat)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Stack className='h-full grow overflow-auto'>
|
||||
<div className='flex h-full grow flex-col overflow-auto'>
|
||||
<ChatList onClickChat={handleClickChat} />
|
||||
</Stack>
|
||||
</Stack>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -2,9 +2,7 @@ import React from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import Combobox, { ComboboxInput } from '@/components/ui/combobox';
|
||||
import HStack from '@/components/ui/hstack';
|
||||
import IconButton from '@/components/ui/icon-button';
|
||||
import Stack from '@/components/ui/stack';
|
||||
import Text from '@/components/ui/text';
|
||||
import { useInstance } from '@/hooks/use-instance';
|
||||
|
||||
@@ -61,8 +59,8 @@ const ShoutboxComposer = React.forwardRef<HTMLTextAreaElement | null, IShoutboxC
|
||||
{/* Spacer */}
|
||||
<div className='h-5' />
|
||||
|
||||
<HStack alignItems='stretch' justifyContent='between' space={4}>
|
||||
<Stack grow>
|
||||
<div className='flex items-stretch justify-between gap-4'>
|
||||
<div className='flex flex-grow flex-col'>
|
||||
<Combobox onSelect={onSelectComboboxOption}>
|
||||
<ComboboxInput
|
||||
key={resetContentKey}
|
||||
@@ -80,9 +78,9 @@ const ShoutboxComposer = React.forwardRef<HTMLTextAreaElement | null, IShoutboxC
|
||||
disabled={disabled}
|
||||
/>
|
||||
</Combobox>
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
<Stack space={2} justifyContent='end' alignItems='center' className='mb-1.5 w-10'>
|
||||
<div className='mb-1.5 flex w-10 flex-col items-center justify-end gap-2'>
|
||||
{isOverCharacterLimit ? (
|
||||
<Text size='sm' theme='danger'>
|
||||
{overLimitText}
|
||||
@@ -97,8 +95,8 @@ const ShoutboxComposer = React.forwardRef<HTMLTextAreaElement | null, IShoutboxC
|
||||
onClick={onSubmit}
|
||||
title={intl.formatMessage(messages.send)}
|
||||
/>
|
||||
</Stack>
|
||||
</HStack>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='h-5' />
|
||||
</div>
|
||||
|
||||
@@ -6,8 +6,6 @@ import { Virtuoso, type VirtuosoHandle } from 'react-virtuoso';
|
||||
import HoverAccountWrapper from '@/components/accounts/hover-account-wrapper';
|
||||
import { ParsedContent } from '@/components/statuses/parsed-content';
|
||||
import Avatar from '@/components/ui/avatar';
|
||||
import HStack from '@/components/ui/hstack';
|
||||
import Stack from '@/components/ui/stack';
|
||||
import Text from '@/components/ui/text';
|
||||
import Emojify from '@/features/emoji/emojify';
|
||||
import PlaceholderChatMessage from '@/features/placeholder/components/placeholder-chat-message';
|
||||
@@ -34,12 +32,10 @@ const ShoutboxMessage: React.FC<IShoutboxMessage> = ({ message, isMyMessage }) =
|
||||
key={message.id}
|
||||
className='group relative px-4 py-2 hover:bg-gray-200/40 dark:hover:bg-gray-800/40'
|
||||
>
|
||||
<HStack
|
||||
space={2}
|
||||
alignItems='bottom'
|
||||
justifyContent={isMyMessage ? 'end' : 'start'}
|
||||
className={clsx({
|
||||
'ml-auto': isMyMessage,
|
||||
<div
|
||||
className={clsx('flex items-end gap-2', {
|
||||
'ml-auto justify-end': isMyMessage,
|
||||
'justify-start': !isMyMessage,
|
||||
})}
|
||||
>
|
||||
{!isMyMessage && (
|
||||
@@ -61,39 +57,35 @@ const ShoutboxMessage: React.FC<IShoutboxMessage> = ({ message, isMyMessage }) =
|
||||
</Link>
|
||||
)}
|
||||
|
||||
<Stack
|
||||
space={0.5}
|
||||
className={clsx({
|
||||
<div
|
||||
className={clsx('flex flex-col gap-0.5', {
|
||||
'max-w-[85%]': true,
|
||||
'order-3': isMyMessage,
|
||||
'order-1': !isMyMessage,
|
||||
'order-3 items-end': isMyMessage,
|
||||
'order-1 items-start': !isMyMessage,
|
||||
})}
|
||||
alignItems={isMyMessage ? 'end' : 'start'}
|
||||
>
|
||||
<HStack alignItems='bottom' className='max-w-full'>
|
||||
<div
|
||||
className={clsx({
|
||||
'relative max-w-full space-y-2 text-ellipsis break-words rounded-md px-3 py-2 [&_.mention]:underline': true,
|
||||
'[&_.mention]:text-primary-600 dark:[&_.mention]:text-primary-400': !isMyMessage,
|
||||
'dark:[&_.mention]:white [&_.mention]:text-white': isMyMessage,
|
||||
'bg-primary-500 text-white': isMyMessage,
|
||||
'bg-gray-200 text-gray-900 dark:bg-gray-800 dark:text-gray-100': !isMyMessage,
|
||||
// '!bg-transparent !p-0 emoji-lg': isOnlyEmoji,
|
||||
})}
|
||||
tabIndex={0}
|
||||
>
|
||||
<Text size='sm' theme='inherit' className='break-word-nested'>
|
||||
<ParsedContent html={message.text} />
|
||||
</Text>
|
||||
</div>
|
||||
</HStack>
|
||||
<div
|
||||
className={clsx({
|
||||
'relative max-w-full space-y-2 text-ellipsis break-words rounded-md px-3 py-2 [&_.mention]:underline': true,
|
||||
'[&_.mention]:text-primary-600 dark:[&_.mention]:text-primary-400': !isMyMessage,
|
||||
'dark:[&_.mention]:white [&_.mention]:text-white': isMyMessage,
|
||||
'bg-primary-500 text-white': isMyMessage,
|
||||
'bg-gray-200 text-gray-900 dark:bg-gray-800 dark:text-gray-100': !isMyMessage,
|
||||
// '!bg-transparent !p-0 emoji-lg': isOnlyEmoji,
|
||||
})}
|
||||
tabIndex={0}
|
||||
>
|
||||
<Text size='sm' theme='inherit' className='break-word-nested'>
|
||||
<ParsedContent html={message.text} />
|
||||
</Text>
|
||||
</div>
|
||||
{!isMyMessage && (
|
||||
<Text size='xs' theme='muted'>
|
||||
<Emojify text={account.display_name} emojis={account.emojis} />
|
||||
</Text>
|
||||
)}
|
||||
</Stack>
|
||||
</HStack>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -10,7 +10,6 @@ import DropdownMenu, { type Menu as MenuType } from '@/components/dropdown-menu'
|
||||
import Icon from '@/components/icon';
|
||||
import StillImage from '@/components/still-image';
|
||||
import Button from '@/components/ui/button';
|
||||
import HStack from '@/components/ui/hstack';
|
||||
import IconButton from '@/components/ui/icon-button';
|
||||
import Text from '@/components/ui/text';
|
||||
import Emojify from '@/features/emoji/emojify';
|
||||
@@ -510,12 +509,12 @@ const EventHeader: React.FC<IEventHeader> = ({ status }) => {
|
||||
to='/@{$username}'
|
||||
params={{ username: account.acct }}
|
||||
>
|
||||
<HStack space={1} alignItems='center' grow>
|
||||
<div className='flex flex-grow items-center gap-1'>
|
||||
<span>
|
||||
<Emojify text={account.display_name} emojis={account.emojis} />
|
||||
</span>
|
||||
{account.verified && <VerificationBadge />}
|
||||
</HStack>
|
||||
</div>
|
||||
</Link>
|
||||
),
|
||||
}}
|
||||
|
||||
@@ -2,8 +2,6 @@ import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import Icon from '@/components/icon';
|
||||
import HStack from '@/components/ui/hstack';
|
||||
import Stack from '@/components/ui/stack';
|
||||
import Text from '@/components/ui/text';
|
||||
import { useInstance } from '@/hooks/use-instance';
|
||||
|
||||
@@ -20,11 +18,11 @@ interface IRestriction {
|
||||
}
|
||||
|
||||
const Restriction: React.FC<IRestriction> = ({ icon, children }) => (
|
||||
<HStack space={3}>
|
||||
<div className='flex gap-3'>
|
||||
<Icon className='size-5 flex-none' src={icon} />
|
||||
|
||||
<Text theme='muted'>{children}</Text>
|
||||
</HStack>
|
||||
</div>
|
||||
);
|
||||
|
||||
interface IInstanceRestrictions {
|
||||
@@ -155,7 +153,7 @@ const InstanceRestrictions: React.FC<IInstanceRestrictions> = ({ remoteInstance
|
||||
}
|
||||
};
|
||||
|
||||
return <Stack space={3}>{renderContent()}</Stack>;
|
||||
return <div className='flex flex-col gap-3'>{renderContent()}</div>;
|
||||
};
|
||||
|
||||
export { InstanceRestrictions as default };
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import { useIntl, defineMessages } from 'react-intl';
|
||||
|
||||
import HStack from '@/components/ui/hstack';
|
||||
import Input from '@/components/ui/input';
|
||||
|
||||
import type { StreamfieldComponent } from '@/components/ui/streamfield';
|
||||
@@ -32,7 +31,7 @@ const CryptoAddressInput: StreamfieldComponent<CryptoAddress> = ({ value, onChan
|
||||
};
|
||||
|
||||
return (
|
||||
<HStack space={2} grow>
|
||||
<div className='flex grow flex-col gap-2'>
|
||||
<Input
|
||||
type='text'
|
||||
outerClassName='w-1/6 grow'
|
||||
@@ -54,7 +53,7 @@ const CryptoAddressInput: StreamfieldComponent<CryptoAddress> = ({ value, onChan
|
||||
onChange={handleChange('note')}
|
||||
placeholder={intl.formatMessage(messages.note)}
|
||||
/>
|
||||
</HStack>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import { useIntl, defineMessages } from 'react-intl';
|
||||
|
||||
import HStack from '@/components/ui/hstack';
|
||||
import Input from '@/components/ui/input';
|
||||
|
||||
import type { StreamfieldComponent } from '@/components/ui/streamfield';
|
||||
@@ -25,7 +24,7 @@ const PromoPanelInput: StreamfieldComponent<FooterItem> = ({ value, onChange })
|
||||
};
|
||||
|
||||
return (
|
||||
<HStack space={2} grow>
|
||||
<div className='flex flex-grow gap-2'>
|
||||
<Input
|
||||
type='text'
|
||||
outerClassName='w-full grow'
|
||||
@@ -40,7 +39,7 @@ const PromoPanelInput: StreamfieldComponent<FooterItem> = ({ value, onChange })
|
||||
value={value.url}
|
||||
onChange={handleChange('url')}
|
||||
/>
|
||||
</HStack>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -43,13 +43,11 @@ const GroupTimelinePage: React.FC = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div clsasName='flex flex-col gap-2'>
|
||||
<div className='flex flex-col gap-2'>
|
||||
{canComposeGroupStatus && (
|
||||
<div className='border-b border-solid border-gray-200 py-6 dark:border-gray-800'>
|
||||
<div
|
||||
ref={composer}
|
||||
alignItems='start'
|
||||
space={2}
|
||||
className={clsx('relative flex items-start gap-2 rounded-xl transition', {
|
||||
'z-[99] border-2 border-dashed border-primary-600 p-4': isDragging,
|
||||
'ring-2 ring-primary-600 ring-offset-2': isDraggedOver,
|
||||
|
||||
Reference in New Issue
Block a user