diff --git a/app/soapbox/contexts/chat-context.tsx b/app/soapbox/contexts/chat-context.tsx index 9694e56644..82d3106ab8 100644 --- a/app/soapbox/contexts/chat-context.tsx +++ b/app/soapbox/contexts/chat-context.tsx @@ -11,13 +11,16 @@ type WindowState = 'open' | 'minimized'; const ChatContext = createContext({ chat: null, isOpen: false, + isEditing: false, }); const ChatProvider: React.FC = ({ children }) => { const dispatch = useDispatch(); const settings = useSettings(); - const [chat, setChat] = useState(); + const [chat, setChat] = useState(null); + const [isEditing, setEditing] = useState(false); + const mainWindowState = settings.getIn(['chats', 'mainWindow']) as WindowState; const isOpen = mainWindowState === 'open'; @@ -25,14 +28,18 @@ const ChatProvider: React.FC = ({ children }) => { const toggleChatPane = () => dispatch(toggleMainWindow()); return ( - {children} + + {children} + ); }; interface IChatContext { chat: IChat | null isOpen: boolean + isEditing: boolean setChat: React.Dispatch> + setEditing: React.Dispatch> toggleChatPane(): void } diff --git a/app/soapbox/features/chats/components/chat-pane.tsx b/app/soapbox/features/chats/components/chat-pane.tsx index 14ce46f097..2279947d65 100644 --- a/app/soapbox/features/chats/components/chat-pane.tsx +++ b/app/soapbox/features/chats/components/chat-pane.tsx @@ -106,7 +106,7 @@ const ChatPane = () => { {account.display_name} {account.verified && } - {account.acct} + @{account.acct} @@ -128,10 +128,10 @@ const ChatPane = () => {
- {chat.account?.display_name} + {chat.account?.display_name} {chat.account?.verified && }
- {chat.account?.acct} + @{chat.account?.acct}
diff --git a/app/soapbox/features/chats/components/chat-settings.tsx b/app/soapbox/features/chats/components/chat-settings.tsx new file mode 100644 index 0000000000..b3912f33fa --- /dev/null +++ b/app/soapbox/features/chats/components/chat-settings.tsx @@ -0,0 +1,119 @@ +import React from 'react'; + +import { blockAccount } from 'soapbox/actions/accounts'; +import { openModal } from 'soapbox/actions/modals'; +import { initReport } from 'soapbox/actions/reports'; +import List, { ListItem } from 'soapbox/components/list'; +import { Avatar, Divider, HStack, Icon, Stack, Text, Toggle } from 'soapbox/components/ui'; +import { useChatContext } from 'soapbox/contexts/chat-context'; +import { useAppDispatch } from 'soapbox/hooks'; +import { useChat } from 'soapbox/queries/chats'; + +import ChatPaneHeader from './chat-pane-header'; + +const ChatSettings = () => { + const dispatch = useAppDispatch(); + + const { chat, setEditing, toggleChatPane } = useChatContext(); + const { deleteChat } = useChat(chat?.id as string); + + const closeSettings = () => setEditing(false); + + const minimizeChatPane = () => { + closeSettings(); + toggleChatPane(); + }; + + const handleBlockUser = () => { + dispatch(openModal('CONFIRM', { + heading: `Block @${chat?.account.acct}`, + message: 'Blocking will prevent this profile from direct messaging you and viewing your content. You can unblock later.', + confirm: 'Block', + confirmationTheme: 'primary', + onConfirm: () => dispatch(blockAccount(chat?.account.id)), + })); + }; + + const handleLeaveChat = () => { + dispatch(openModal('CONFIRM', { + heading: 'Leave Chat', + message: 'Are you sure you want to leave this chat? This conversation will be removed from your inbox.', + confirm: 'Leave Chat', + confirmationTheme: 'primary', + onConfirm: () => { + deleteChat.mutate(); + }, + })); + }; + + const handleReportChat = () => { + dispatch(initReport(chat?.account)); + }; + + if (!chat) { + return null; + } + + return ( + <> + + + + + Chat Details + + + } + /> + + + + + + {chat.account.display_name} + @{chat.account.acct} + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default ChatSettings; diff --git a/app/soapbox/features/chats/components/chat-window.tsx b/app/soapbox/features/chats/components/chat-window.tsx index 292232478e..df9dc02a42 100644 --- a/app/soapbox/features/chats/components/chat-window.tsx +++ b/app/soapbox/features/chats/components/chat-window.tsx @@ -6,21 +6,29 @@ import { useChatContext } from 'soapbox/contexts/chat-context'; import ChatBox from './chat-box'; import ChatPaneHeader from './chat-pane-header'; +import ChatSettings from './chat-settings'; /** Floating desktop chat window. */ const ChatWindow = () => { - const { chat, setChat, isOpen, toggleChatPane } = useChatContext(); + const { chat, setChat, isOpen, isEditing, setEditing, toggleChatPane } = useChatContext(); const inputRef = useRef(); const closeChat = () => setChat(null); + const openAndFocusChat = () => { toggleChatPane(); inputRef.current?.focus(); }; + const openChatSettings = () => setEditing(true); + if (!chat) return null; + if (isEditing) { + return ; + } + return ( <> {
- {chat.account.display_name} + {chat.account.display_name} {chat.account.verified && }
- {chat.account.acct} + @{chat.account.acct}
} - secondaryAction={isOpen ? undefined : openAndFocusChat} - secondaryActionIcon={isOpen ? undefined : require('@tabler/icons/edit.svg')} + secondaryAction={isOpen ? openChatSettings : openAndFocusChat} + secondaryActionIcon={isOpen ? require('@tabler/icons/info-circle.svg') : require('@tabler/icons/edit.svg')} isToggleable={!isOpen} isOpen={isOpen} onToggle={toggleChatPane} diff --git a/app/soapbox/features/chats/components/ui/pane.tsx b/app/soapbox/features/chats/components/ui/pane.tsx index 3817fbc538..b88f8fa131 100644 --- a/app/soapbox/features/chats/components/ui/pane.tsx +++ b/app/soapbox/features/chats/components/ui/pane.tsx @@ -18,7 +18,7 @@ const Pane: React.FC = ({ isOpen = false, index, children, main = false } return (