diff --git a/web/chat/pinned-messages-banner.css b/web/chat/pinned-messages-banner.css new file mode 100644 index 000000000..bf4f876f8 --- /dev/null +++ b/web/chat/pinned-messages-banner.css @@ -0,0 +1,24 @@ +.container { + background-color: var(--frame-background-secondary-default); + height: 40px; + text-align: center; + display: flex; + align-items: center; + justify-content: center; +} + +a.pinnedCountText { + color: var(--text-background-secondary-default); + font-size: var(--xs-font-12); + display: inline-flex; + align-items: center; +} + +a.pinnedCountText:hover { + cursor: pointer; + text-decoration: underline; +} + +.chevronRight { + vertical-align: middle; +} diff --git a/web/chat/pinned-messages-banner.react.js b/web/chat/pinned-messages-banner.react.js new file mode 100644 index 000000000..8b8f79a03 --- /dev/null +++ b/web/chat/pinned-messages-banner.react.js @@ -0,0 +1,55 @@ +// @flow + +import * as React from 'react'; +import { ChevronRight } from 'react-feather'; + +import { useModalContext } from 'lib/components/modal-provider.react.js'; +import type { ThreadInfo } from 'lib/types/thread-types.js'; +import { pinnedMessageCountText } from 'lib/utils/message-pinning-utils.js'; + +import css from './pinned-messages-banner.css'; +import { InputStateContext } from '../input/input-state.js'; +import PinnedMessagesModal from '../modals/chat/pinned-messages-modal.react.js'; + +type Props = { + +threadInfo: ThreadInfo, +}; + +function PinnedMessagesBanner(props: Props): React.Node { + const { threadInfo } = props; + + const { pushModal } = useModalContext(); + + const inputState = React.useContext(InputStateContext); + + const pushThreadPinsModal = React.useCallback(() => { + pushModal( + + + , + ); + }, [pushModal, inputState, threadInfo]); + + const pinnedMessagesBanner = React.useMemo(() => { + const bannerText = + !!threadInfo.pinnedCount && + pinnedMessageCountText(threadInfo.pinnedCount); + + if (!bannerText) { + return null; + } + + return ( +
+ + {bannerText} + + +
+ ); + }, [pushThreadPinsModal, threadInfo.pinnedCount]); + + return pinnedMessagesBanner; +} + +export default PinnedMessagesBanner; diff --git a/web/chat/thread-top-bar.css b/web/chat/thread-top-bar.css index 144f9cc8e..eccf6cdb4 100644 --- a/web/chat/thread-top-bar.css +++ b/web/chat/thread-top-bar.css @@ -1,60 +1,35 @@ div.topBarContainer { display: flex; background-color: var(--bg); align-items: center; justify-content: space-between; padding: 16px; color: var(--thread-top-bar-color); border-bottom: 1px solid var(--border); } div.topBarThreadInfo { height: 24px; display: flex; align-items: center; column-gap: 8px; overflow: hidden; } .threadTitle { font-size: var(--m-font-16); font-weight: var(--bold); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } -.pinnedCountBanner { - background-color: var(--pinned-count-banner-color); - height: 40px; - text-align: center; - display: flex; - align-items: center; - justify-content: center; -} - -a.pinnedCountText { - color: var(--pinned-count-text-color); - font-size: var(--xs-font-12); - display: inline-flex; - align-items: center; -} - -a.pinnedCountText:hover { - cursor: pointer; - text-decoration: underline; -} - -.chevronRight { - vertical-align: middle; -} - .searchButtonIcon { color: var(--thread-top-bar-search-button-color); } .buttons { flex-direction: row; display: flex; gap: 30px; } diff --git a/web/chat/thread-top-bar.react.js b/web/chat/thread-top-bar.react.js index a5fdfe29f..76020bdef 100644 --- a/web/chat/thread-top-bar.react.js +++ b/web/chat/thread-top-bar.react.js @@ -1,95 +1,68 @@ // @flow import * as React from 'react'; -import { ChevronRight } from 'react-feather'; import { useModalContext } from 'lib/components/modal-provider.react.js'; import SWMansionIcon from 'lib/components/SWMansionIcon.react.js'; import { threadIsPending } from 'lib/shared/thread-utils.js'; import type { ThreadInfo } from 'lib/types/thread-types.js'; import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js'; -import { pinnedMessageCountText } from 'lib/utils/message-pinning-utils.js'; +import PinnedMessagesBanner from './pinned-messages-banner.react.js'; import ThreadMenu from './thread-menu.react.js'; import css from './thread-top-bar.css'; import ThreadAvatar from '../avatars/thread-avatar.react.js'; import Button from '../components/button.react.js'; import { InputStateContext } from '../input/input-state.js'; -import PinnedMessagesModal from '../modals/chat/pinned-messages-modal.react.js'; import MessageSearchModal from '../modals/search/message-search-modal.react.js'; type ThreadTopBarProps = { +threadInfo: ThreadInfo, }; function ThreadTopBar(props: ThreadTopBarProps): React.Node { const { threadInfo } = props; const { pushModal } = useModalContext(); let threadMenu = null; if (!threadIsPending(threadInfo.id)) { threadMenu = ; } - const bannerText = - !!threadInfo.pinnedCount && pinnedMessageCountText(threadInfo.pinnedCount); - const inputState = React.useContext(InputStateContext); - const pushThreadPinsModal = React.useCallback(() => { - pushModal( - - - , - ); - }, [pushModal, inputState, threadInfo]); - - const pinnedCountBanner = React.useMemo(() => { - if (!bannerText) { - return null; - } - - return ( -
- - {bannerText} - - -
- ); - }, [bannerText, pushThreadPinsModal]); const onClickSearch = React.useCallback( () => pushModal( , ), [inputState, pushModal, threadInfo], ); const { uiName } = useResolvedThreadInfo(threadInfo); return ( <>
{uiName}
{threadMenu}
- {pinnedCountBanner} + ); } export default ThreadTopBar;