Chats: break out Pane into a UI component

This commit is contained in:
Alex Gleason 2022-07-20 15:32:25 -05:00 committed by Justin
parent f16da850fd
commit 0b4fc43172
4 changed files with 42 additions and 10 deletions

View File

@ -15,6 +15,7 @@ import { Chat } from 'soapbox/types/entities';
import ChatList from './chat-list'; import ChatList from './chat-list';
import ChatWindow from './chat-window'; import ChatWindow from './chat-window';
import { Pane, WindowState } from './ui';
const messages = defineMessages({ const messages = defineMessages({
searchPlaceholder: { id: 'chats.search_placeholder', defaultMessage: 'Start a chat with…' }, searchPlaceholder: { id: 'chats.search_placeholder', defaultMessage: 'Start a chat with…' },
@ -43,7 +44,7 @@ const ChatPanes = () => {
const history = useHistory(); const history = useHistory();
const panes = useAppSelector((state) => normalizeChatPanes(state)); const panes = useAppSelector((state) => normalizeChatPanes(state));
const mainWindowState = useSettings().getIn(['chats', 'mainWindow']); const mainWindowState = useSettings().getIn(['chats', 'mainWindow']) as WindowState;
const unreadCount = useAppSelector((state) => getChatsUnreadCount(state)); const unreadCount = useAppSelector((state) => getChatsUnreadCount(state));
const handleClickChat = ((chat: Chat) => { const handleClickChat = ((chat: Chat) => {
@ -61,7 +62,7 @@ const ChatPanes = () => {
const open = mainWindowState === 'open'; const open = mainWindowState === 'open';
const mainWindowPane = ( const mainWindowPane = (
<div className={`pane pane--main pane--${mainWindowState}`}> <Pane windowState={mainWindowState} index={0} main>
<div className='pane__header'> <div className='pane__header'>
{unreadCount > 0 && ( {unreadCount > 0 && (
<div className='mr-2 flex-none'> <div className='mr-2 flex-none'>
@ -87,7 +88,7 @@ const ChatPanes = () => {
</> </>
)} )}
</div> </div>
</div> </Pane>
); );
return ( return (
@ -95,7 +96,7 @@ const ChatPanes = () => {
{mainWindowPane} {mainWindowPane}
{panes.map((pane, i) => ( {panes.map((pane, i) => (
<ChatWindow <ChatWindow
idx={i} idx={i + 1}
key={pane.get('chat_id')} key={pane.get('chat_id')}
chatId={pane.get('chat_id')} chatId={pane.get('chat_id')}
windowState={pane.get('state')} windowState={pane.get('state')}

View File

@ -15,11 +15,10 @@ import { getAcct } from 'soapbox/utils/accounts';
import { displayFqn as getDisplayFqn } from 'soapbox/utils/state'; import { displayFqn as getDisplayFqn } from 'soapbox/utils/state';
import ChatBox from './chat-box'; import ChatBox from './chat-box';
import { Pane, WindowState } from './ui';
import type { Account as AccountEntity } from 'soapbox/types/entities'; import type { Account as AccountEntity } from 'soapbox/types/entities';
type WindowState = 'open' | 'minimized';
const getChat = makeGetChat(); const getChat = makeGetChat();
interface IChatWindow { interface IChatWindow {
@ -72,8 +71,6 @@ const ChatWindow: React.FC<IChatWindow> = ({ idx, chatId, windowState }) => {
if (!chat) return null; if (!chat) return null;
const account = chat.account as unknown as AccountEntity; const account = chat.account as unknown as AccountEntity;
const right = (285 * (idx + 1)) + 20;
const unreadCount = chat.unread; const unreadCount = chat.unread;
const unreadIcon = ( const unreadIcon = (
@ -91,7 +88,7 @@ const ChatWindow: React.FC<IChatWindow> = ({ idx, chatId, windowState }) => {
); );
return ( return (
<div className={`pane pane--${windowState}`} style={{ right: `${right}px` }}> <Pane windowState={windowState} index={idx}>
<HStack space={2} className='pane__header'> <HStack space={2} className='pane__header'>
{unreadCount > 0 ? unreadIcon : avatar } {unreadCount > 0 ? unreadIcon : avatar }
<button className='pane__title' onClick={handleChatToggle(chat.id)}> <button className='pane__title' onClick={handleChatToggle(chat.id)}>
@ -107,7 +104,7 @@ const ChatWindow: React.FC<IChatWindow> = ({ idx, chatId, windowState }) => {
onSetInputRef={handleInputRef} onSetInputRef={handleInputRef}
/> />
</div> </div>
</div> </Pane>
); );
}; };

View File

@ -0,0 +1,2 @@
export { Pane } from './pane';
export type { WindowState } from './pane';

View File

@ -0,0 +1,32 @@
import classNames from 'classnames';
import React from 'react';
/** Chat pane state. */
export type WindowState = 'open' | 'minimized';
interface IPane {
/** Whether the pane is open or minimized. */
windowState: WindowState,
/** Positions the pane on the screen, with 0 at the right. */
index: number,
/** Children to display in the pane. */
children: React.ReactNode,
/** Whether this is the main chat pane. */
main?: boolean,
}
/** Chat pane UI component for desktop. */
const Pane: React.FC<IPane> = ({ windowState, index, children, main = false }) => {
const right = (285 * index) + 20;
return (
<div
className={classNames(`pane pane--${windowState}`, { 'pane--main': main })}
style={{ right: `${right}px` }}
>
{children}
</div>
);
};
export { Pane };