pl-fe: chat accessibility improvements
Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
@ -1,8 +1,14 @@
|
||||
import React, { HTMLAttributes } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import IconButton from '@/components/ui/icon-button';
|
||||
import { useSettings } from '@/stores/settings';
|
||||
|
||||
const messages = defineMessages({
|
||||
expand: { id: 'chat_pane.header.expand', defaultMessage: 'Expand chats' },
|
||||
collapse: { id: 'chat_pane.header.collapse', defaultMessage: 'Collapse chats' },
|
||||
});
|
||||
|
||||
interface IChatPaneHeader {
|
||||
isOpen: boolean;
|
||||
isToggleable?: boolean;
|
||||
@ -11,6 +17,7 @@ interface IChatPaneHeader {
|
||||
unreadCount?: number;
|
||||
secondaryAction?(): void;
|
||||
secondaryActionIcon?: string;
|
||||
secondaryActionTitle?: string;
|
||||
}
|
||||
|
||||
const ChatPaneHeader = (props: IChatPaneHeader) => {
|
||||
@ -20,11 +27,13 @@ const ChatPaneHeader = (props: IChatPaneHeader) => {
|
||||
onToggle,
|
||||
secondaryAction,
|
||||
secondaryActionIcon,
|
||||
secondaryActionTitle,
|
||||
title,
|
||||
unreadCount,
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
const intl = useIntl();
|
||||
const { demetricator } = useSettings();
|
||||
|
||||
const ButtonComp = isToggleable ? 'button' : 'div';
|
||||
@ -54,10 +63,11 @@ const ChatPaneHeader = (props: IChatPaneHeader) => {
|
||||
</ButtonComp>
|
||||
|
||||
<div className='⁂-chat-widget__header__actions'>
|
||||
{secondaryAction ? (
|
||||
{secondaryAction && secondaryActionIcon ? (
|
||||
<IconButton
|
||||
onClick={secondaryAction}
|
||||
src={secondaryActionIcon as string}
|
||||
src={secondaryActionIcon}
|
||||
title={secondaryActionTitle}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
@ -65,6 +75,7 @@ const ChatPaneHeader = (props: IChatPaneHeader) => {
|
||||
onClick={onToggle}
|
||||
src={require('@phosphor-icons/core/regular/caret-up.svg')}
|
||||
className='⁂-chat-widget__header__open-button'
|
||||
title={isOpen ? intl.formatMessage(messages.collapse) : intl.formatMessage(messages.expand)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import Avatar from '@/components/ui/avatar';
|
||||
import HStack from '@/components/ui/hstack';
|
||||
@ -15,19 +15,12 @@ import { useModalsActions } from '@/stores/modals';
|
||||
import ChatPaneHeader from './chat-pane-header';
|
||||
|
||||
const messages = defineMessages({
|
||||
blockMessage: { id: 'chat_settings.block.message', defaultMessage: 'Blocking will prevent this profile from direct messaging you and viewing your content. You can unblock later.' },
|
||||
blockHeading: { id: 'chat_settings.block.heading', defaultMessage: 'Block @{acct}' },
|
||||
blockConfirm: { id: 'chat_settings.block.confirm', defaultMessage: 'Block' },
|
||||
unblockMessage: { id: 'chat_settings.unblock.message', defaultMessage: 'Unblocking will allow this profile to direct message you and view your content.' },
|
||||
back: { id: 'card.back.label', defaultMessage: 'Back' },
|
||||
unblockHeading: { id: 'chat_settings.unblock.heading', defaultMessage: 'Unblock @{acct}' },
|
||||
unblockConfirm: { id: 'chat_settings.unblock.confirm', defaultMessage: 'Unblock' },
|
||||
leaveMessage: { id: 'chat_settings.leave.message', defaultMessage: 'Are you sure you want to leave this chat? Messages will be deleted for you and this chat will be removed from your inbox.' },
|
||||
leaveHeading: { id: 'chat_settings.leave.heading', defaultMessage: 'Leave chat' },
|
||||
leaveConfirm: { id: 'chat_settings.leave.confirm', defaultMessage: 'Leave chat' },
|
||||
title: { id: 'chat_settings.title', defaultMessage: 'Chat Details' },
|
||||
blockUser: { id: 'chat_settings.options.block_user', defaultMessage: 'Block @{acct}' },
|
||||
unblockUser: { id: 'chat_settings.options.unblock_user', defaultMessage: 'Unblock @{acct}' },
|
||||
leaveChat: { id: 'chat_settings.options.leave_chat', defaultMessage: 'Leave chat' },
|
||||
});
|
||||
|
||||
const ChatSettings = () => {
|
||||
@ -61,7 +54,7 @@ const ChatSettings = () => {
|
||||
const handleUnblockUser = () => {
|
||||
openModal('CONFIRM', {
|
||||
heading: intl.formatMessage(messages.unblockHeading, { acct: chat?.account.acct }),
|
||||
message: intl.formatMessage(messages.unblockMessage),
|
||||
message: <FormattedMessage id='chat_settings.unblock.message' defaultMessage='Unblocking will allow this profile to direct message you and view your content.' />,
|
||||
confirm: intl.formatMessage(messages.unblockConfirm),
|
||||
onConfirm: () => unblockAccount(),
|
||||
});
|
||||
@ -70,7 +63,7 @@ const ChatSettings = () => {
|
||||
const handleLeaveChat = () => {
|
||||
openModal('CONFIRM', {
|
||||
heading: intl.formatMessage(messages.leaveHeading),
|
||||
message: intl.formatMessage(messages.leaveMessage),
|
||||
message: <FormattedMessage id='chat_settings.leave.message' defaultMessage='Are you sure you want to leave this chat? Messages will be deleted for you and this chat will be removed from your inbox.' />,
|
||||
confirm: intl.formatMessage(messages.leaveConfirm),
|
||||
onConfirm: () => deleteChat.mutate(),
|
||||
});
|
||||
@ -88,7 +81,7 @@ const ChatSettings = () => {
|
||||
onToggle={minimizeChatPane}
|
||||
title={
|
||||
<HStack alignItems='center' space={2}>
|
||||
<button onClick={closeSettings}>
|
||||
<button onClick={closeSettings} title={intl.formatMessage(messages.back)}>
|
||||
<Icon
|
||||
src={require('@phosphor-icons/core/regular/arrow-left.svg')}
|
||||
className='size-6 text-gray-600 dark:text-gray-400 rtl:rotate-180'
|
||||
@ -96,7 +89,7 @@ const ChatSettings = () => {
|
||||
</button>
|
||||
|
||||
<Text weight='semibold'>
|
||||
{intl.formatMessage(messages.title)}
|
||||
<FormattedMessage id='chat_settings.title' defaultMessage='Chat details' />
|
||||
</Text>
|
||||
</HStack>
|
||||
}
|
||||
@ -113,14 +106,20 @@ const ChatSettings = () => {
|
||||
|
||||
<Stack space={5}>
|
||||
<button onClick={isBlocked ? handleUnblockUser : handleBlockUser} className='flex w-full items-center space-x-2 text-sm font-bold text-primary-600 dark:text-primary-400'>
|
||||
<Icon src={require('@phosphor-icons/core/regular/prohibit.svg')} className='size-5' />
|
||||
<span>{intl.formatMessage(isBlocked ? messages.unblockUser : messages.blockUser, { acct: chat.account.acct })}</span>
|
||||
<Icon src={require('@phosphor-icons/core/regular/prohibit.svg')} className='size-5' aria-hidden />
|
||||
<span>
|
||||
{isBlocked
|
||||
? <FormattedMessage id='chat_settings.options.unblock_user' defaultMessage='Unblock @{acct}' values={{ acct: chat.account.acct }} />
|
||||
: <FormattedMessage id='chat_settings.options.block_user' defaultMessage='Block @{acct}' values={{ acct: chat.account.acct }} />
|
||||
}
|
||||
|
||||
</span>
|
||||
</button>
|
||||
|
||||
{features.chatsDelete && (
|
||||
<button onClick={handleLeaveChat} className='flex w-full items-center space-x-2 text-sm font-bold text-danger-600'>
|
||||
<Icon src={require('@phosphor-icons/core/regular/sign-out.svg')} className='size-5' />
|
||||
<span>{intl.formatMessage(messages.leaveChat)}</span>
|
||||
<Icon src={require('@phosphor-icons/core/regular/sign-out.svg')} className='size-5' aria-hidden />
|
||||
<span><FormattedMessage id='chat_settings.options.leave_chat' defaultMessage='Leave chat' /></span>
|
||||
</button>
|
||||
)}
|
||||
</Stack>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { Link, type LinkProps } from '@tanstack/react-router';
|
||||
import React, { useRef } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import Avatar from '@/components/ui/avatar';
|
||||
import HStack from '@/components/ui/hstack';
|
||||
@ -14,6 +15,12 @@ import Chat from '../chat';
|
||||
import ChatPaneHeader from './chat-pane-header';
|
||||
import ChatSettings from './chat-settings';
|
||||
|
||||
const messages = defineMessages({
|
||||
back: { id: 'card.back.label', defaultMessage: 'Back' },
|
||||
chatInfo: { id: 'chat_pane.header.chat_info', defaultMessage: 'Chat info' },
|
||||
newChat: { id: 'chat_pane.header.new_chat', defaultMessage: 'New chat' },
|
||||
});
|
||||
|
||||
const LinkWrapper = ({ enabled, children, ...rest }: LinkProps & { enabled: boolean; children: React.ReactNode }): JSX.Element => {
|
||||
if (!enabled) {
|
||||
return <>{children}</>;
|
||||
@ -29,6 +36,7 @@ const LinkWrapper = ({ enabled, children, ...rest }: LinkProps & { enabled: bool
|
||||
/** Floating desktop chat window. */
|
||||
const ChatWindow = () => {
|
||||
const { chat, currentChatId, screen, changeScreen, isOpen, toggleChatPane } = useChatContext();
|
||||
const intl = useIntl();
|
||||
|
||||
const inputRef = useRef<HTMLTextAreaElement | null>(null);
|
||||
|
||||
@ -45,8 +53,6 @@ const ChatWindow = () => {
|
||||
changeScreen(ChatWidgetScreens.CHAT_SETTINGS, currentChatId);
|
||||
};
|
||||
|
||||
const secondaryAction = () => isOpen ? openChatSettings : openSearch;
|
||||
|
||||
if (!chat) return null;
|
||||
|
||||
if (screen === ChatWidgetScreens.CHAT_SETTINGS) {
|
||||
@ -59,7 +65,7 @@ const ChatWindow = () => {
|
||||
title={
|
||||
<HStack alignItems='center' space={2}>
|
||||
{isOpen && (
|
||||
<button onClick={closeChat}>
|
||||
<button onClick={closeChat} title={intl.formatMessage(messages.back)}>
|
||||
<Icon
|
||||
src={require('@phosphor-icons/core/regular/arrow-left.svg')}
|
||||
className='size-6 text-gray-600 dark:text-gray-400 rtl:rotate-180'
|
||||
@ -85,8 +91,9 @@ const ChatWindow = () => {
|
||||
</HStack>
|
||||
</HStack>
|
||||
}
|
||||
secondaryAction={secondaryAction()}
|
||||
secondaryAction={isOpen ? openChatSettings : openSearch}
|
||||
secondaryActionIcon={isOpen ? require('@phosphor-icons/core/regular/info.svg') : require('@phosphor-icons/core/regular/pencil-simple.svg')}
|
||||
secondaryActionTitle={isOpen ? intl.formatMessage(messages.chatInfo) : intl.formatMessage(messages.newChat)}
|
||||
isToggleable={!isOpen}
|
||||
isOpen={isOpen}
|
||||
onToggle={toggleChatPane}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import Icon from '@/components/ui/icon';
|
||||
import Text from '@/components/ui/text';
|
||||
@ -8,7 +8,7 @@ import { ChatWidgetScreens, useChatContext } from '@/contexts/chat-context';
|
||||
import ChatPaneHeader from '../chat-pane-header';
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'chat_search.title', defaultMessage: 'Messages' },
|
||||
back: { id: 'card.back.label', defaultMessage: 'Back' },
|
||||
});
|
||||
|
||||
const ChatSearchHeader = () => {
|
||||
@ -25,6 +25,7 @@ const ChatSearchHeader = () => {
|
||||
onClick={() => {
|
||||
changeScreen(ChatWidgetScreens.INBOX);
|
||||
}}
|
||||
title={intl.formatMessage(messages.back)}
|
||||
>
|
||||
<Icon
|
||||
src={require('@phosphor-icons/core/regular/arrow-left.svg')}
|
||||
@ -33,7 +34,7 @@ const ChatSearchHeader = () => {
|
||||
</button>
|
||||
|
||||
<Text size='sm' weight='bold' truncate>
|
||||
{intl.formatMessage(messages.title)}
|
||||
<FormattedMessage id='chat_search.title' defaultMessage='Messages' />
|
||||
</Text>
|
||||
</div>
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ const Pane: React.FC<IPane> = ({ isOpen = false, children }) => (
|
||||
<div
|
||||
className={clsx('⁂-chat-widget', { '⁂-chat-widget--open': isOpen })}
|
||||
data-testid='pane'
|
||||
aria-expanded={isOpen}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
|
||||
@ -336,6 +336,10 @@
|
||||
"chat_pane.blankslate.action": "Message someone",
|
||||
"chat_pane.blankslate.body": "Search for someone to chat with.",
|
||||
"chat_pane.blankslate.title": "No messages yet",
|
||||
"chat_pane.header.chat_info": "Chat info",
|
||||
"chat_pane.header.collapse": "Collapse chats",
|
||||
"chat_pane.header.expand": "Expand chats",
|
||||
"chat_pane.header.new_chat": "New chat",
|
||||
"chat_search.blankslate.body": "Search for someone to chat with.",
|
||||
"chat_search.blankslate.title": "Start a chat",
|
||||
"chat_search.empty_results_blankslate.body": "Try searching for another name.",
|
||||
@ -351,7 +355,7 @@
|
||||
"chat_settings.options.block_user": "Block @{acct}",
|
||||
"chat_settings.options.leave_chat": "Leave chat",
|
||||
"chat_settings.options.unblock_user": "Unblock @{acct}",
|
||||
"chat_settings.title": "Chat Details",
|
||||
"chat_settings.title": "Chat details",
|
||||
"chat_settings.unblock.confirm": "Unblock",
|
||||
"chat_settings.unblock.heading": "Unblock @{acct}",
|
||||
"chat_settings.unblock.message": "Unblocking will allow this profile to direct message you and view your content.",
|
||||
|
||||
Reference in New Issue
Block a user