diff --git a/web/chat/chat-tabs.react.js b/web/chat/chat-tabs.react.js index ef1077290..2da8c4674 100644 --- a/web/chat/chat-tabs.react.js +++ b/web/chat/chat-tabs.react.js @@ -1,48 +1,55 @@ // @flow import * as React from 'react'; import { unreadBackgroundCount } from 'lib/selectors/thread-selectors'; import { useSelector } from '../redux/redux-utils'; import css from './chat-tabs.css'; import ChatThreadBackground from './chat-thread-background.react'; import ChatThreadHome from './chat-thread-home.react'; import ChatThreadTab from './chat-thread-tab.react'; -function ChatTabs() { +type Props = {| + +setModal: (modal: ?React.Node) => void, +|}; +function ChatTabs(props: Props) { let backgroundTitle = 'BACKGROUND'; const unreadBackgroundCountVal = useSelector(unreadBackgroundCount); if (unreadBackgroundCountVal) { backgroundTitle += ` (${unreadBackgroundCountVal})`; } const [activeTab, setActiveTab] = React.useState('HOME'); const onClickHome = React.useCallback(() => setActiveTab('HOME'), []); const onClickBackground = React.useCallback( () => setActiveTab('BACKGROUND'), [], ); const threadList = - activeTab === 'HOME' ? : ; + activeTab === 'HOME' ? ( + + ) : ( + + ); return (
{threadList}
); } export default ChatTabs; diff --git a/web/chat/chat-thread-background.react.js b/web/chat/chat-thread-background.react.js index 4ab48c3ea..6de587b8b 100644 --- a/web/chat/chat-thread-background.react.js +++ b/web/chat/chat-thread-background.react.js @@ -1,24 +1,28 @@ // @flow import * as React from 'react'; import { threadInBackgroundChatList, emptyItemText, } from 'lib/shared/thread-utils'; import css from './chat-tabs.css'; import ChatThreadList from './chat-thread-list.react'; -export default function ChatThreadBackground() { +type Props = {| + +setModal: (modal: ?React.Node) => void, +|}; +export default function ChatThreadBackground(props: Props) { return ( ); } function EmptyItem() { return
{emptyItemText}
; } diff --git a/web/chat/chat-thread-home.react.js b/web/chat/chat-thread-home.react.js index 24b5655a6..2bc9b31ae 100644 --- a/web/chat/chat-thread-home.react.js +++ b/web/chat/chat-thread-home.react.js @@ -1,11 +1,19 @@ // @flow import * as React from 'react'; import { threadInHomeChatList } from 'lib/shared/thread-utils'; import ChatThreadList from './chat-thread-list.react'; -export default function ChatThreadHome() { - return ; +type Props = {| + +setModal: (modal: ?React.Node) => void, +|}; +export default function ChatThreadHome(props: Props) { + return ( + + ); } diff --git a/web/chat/chat-thread-list-item.react.js b/web/chat/chat-thread-list-item.react.js index 5f6d74d07..902b16193 100644 --- a/web/chat/chat-thread-list-item.react.js +++ b/web/chat/chat-thread-list-item.react.js @@ -1,112 +1,114 @@ // @flow import classNames from 'classnames'; import * as React from 'react'; import type { ChatThreadItem } from 'lib/selectors/chat-selectors'; import { shortAbsoluteDate } from 'lib/utils/date-utils'; import { useSelector } from '../redux/redux-utils'; import { useOnClickThread, useThreadIsActive, } from '../selectors/nav-selectors'; import ChatThreadListItemMenu from './chat-thread-list-item-menu.react'; import ChatThreadListSeeMoreSidebars from './chat-thread-list-see-more-sidebars.react'; import ChatThreadListSidebar from './chat-thread-list-sidebar.react'; import css from './chat-thread-list.css'; import MessagePreview from './message-preview.react'; type Props = {| +item: ChatThreadItem, + +setModal: (modal: ?React.Node) => void, |}; function ChatThreadListItem(props: Props) { - const { item } = props; + const { item, setModal } = props; const threadID = item.threadInfo.id; const onClick = useOnClickThread(threadID); const timeZone = useSelector((state) => state.timeZone); const lastActivity = shortAbsoluteDate(item.lastUpdatedTime, timeZone); const active = useThreadIsActive(threadID); const containerClassName = React.useMemo( () => classNames({ [css.thread]: true, [css.activeThread]: active, }), [active], ); const { unread } = item.threadInfo.currentUser; const titleClassName = React.useMemo( () => classNames({ [css.title]: true, [css.unread]: unread, }), [unread], ); const lastActivityClassName = React.useMemo( () => classNames({ [css.lastActivity]: true, [css.unread]: unread, [css.dark]: !unread, }), [unread], ); const { color } = item.threadInfo; const colorSplotchStyle = React.useMemo( () => ({ backgroundColor: `#${color}` }), [color], ); const sidebars = item.sidebars.map((sidebarItem) => { if (sidebarItem.type === 'sidebar') { const { type, ...sidebarInfo } = sidebarItem; return ( ); } else { return ( ); } }); return ( <>
{sidebars} ); } export default ChatThreadListItem; diff --git a/web/chat/chat-thread-list-see-more-sidebars.react.js b/web/chat/chat-thread-list-see-more-sidebars.react.js index 26a79a501..ef6b7b878 100644 --- a/web/chat/chat-thread-list-see-more-sidebars.react.js +++ b/web/chat/chat-thread-list-see-more-sidebars.react.js @@ -1,33 +1,39 @@ // @flow import classNames from 'classnames'; import * as React from 'react'; import DotsThreeHorizontal from 'react-entypo-icons/lib/entypo/DotsThreeHorizontal'; +import SidebarListModal from '../modals/chat/sidebar-list-modal.react'; import css from './chat-thread-list.css'; type Props = {| +unread: boolean, + +setModal: (modal: ?React.Node) => void, |}; function ChatThreadListSeeMoreSidebars(props: Props) { - const { unread } = props; + const { unread, setModal } = props; + const onClick = React.useCallback( + () => setModal(), + [setModal], + ); return ( -
+ ); } export default ChatThreadListSeeMoreSidebars; diff --git a/web/chat/chat-thread-list.react.js b/web/chat/chat-thread-list.react.js index 6693783ad..74044725d 100644 --- a/web/chat/chat-thread-list.react.js +++ b/web/chat/chat-thread-list.react.js @@ -1,33 +1,38 @@ // @flow import * as React from 'react'; import type { ThreadInfo } from 'lib/types/thread-types'; import { useSelector } from '../redux/redux-utils'; import { webChatListData } from '../selectors/chat-selectors'; import ChatThreadListItem from './chat-thread-list-item.react'; type Props = {| +filterThreads: (threadItem: ThreadInfo) => boolean, + +setModal: (modal: ?React.Node) => void, +emptyItem?: React.ComponentType<{||}>, |}; function ChatThreadList(props: Props) { - const { filterThreads, emptyItem } = props; + const { filterThreads, setModal, emptyItem } = props; const chatListData = useSelector(webChatListData); const listData: React.Node[] = React.useMemo(() => { const threads = chatListData .filter((item) => filterThreads(item.threadInfo)) .map((item) => ( - + )); if (threads.length === 0 && emptyItem) { const EmptyItem = emptyItem; threads.push(); } return threads; - }, [chatListData, filterThreads, emptyItem]); + }, [chatListData, emptyItem, filterThreads, setModal]); return
{listData}
; } export default ChatThreadList; diff --git a/web/chat/chat.react.js b/web/chat/chat.react.js index 90890e514..1fa192353 100644 --- a/web/chat/chat.react.js +++ b/web/chat/chat.react.js @@ -1,20 +1,20 @@ // @flow import * as React from 'react'; import ChatMessageList from './chat-message-list.react'; import ChatTabs from './chat-tabs.react'; type Props = {| +setModal: (modal: ?React.Node) => void, |}; function Chat(props: Props) { return ( <> - + ); } export default Chat; diff --git a/web/modals/chat/sidebar-list-modal.react.js b/web/modals/chat/sidebar-list-modal.react.js new file mode 100644 index 000000000..2a7f66fda --- /dev/null +++ b/web/modals/chat/sidebar-list-modal.react.js @@ -0,0 +1,27 @@ +// @flow + +import * as React from 'react'; + +import css from '../../style.css'; +import Modal from '../modal.react'; + +type Props = {| + +setModal: (modal: ?React.Node) => void, +|}; +function SidebarsListModal(props: Props) { + const { setModal } = props; + + const clearModal = React.useCallback(() => { + setModal(null); + }, [setModal]); + + return ( + +
+

Sidebars will be displayed here

+
+
+ ); +} + +export default SidebarsListModal;