diff --git a/lib/hooks/toggle-unread-status.js b/lib/hooks/toggle-unread-status.js new file mode 100644 index 000000000..4a44c4025 --- /dev/null +++ b/lib/hooks/toggle-unread-status.js @@ -0,0 +1,55 @@ +// @flow + +import * as React from 'react'; + +import { + setThreadUnreadStatus, + setThreadUnreadStatusActionTypes, +} from '../actions/activity-actions'; +import type { + SetThreadUnreadStatusPayload, + SetThreadUnreadStatusRequest, +} from '../types/activity-types'; +import type { ThreadInfo } from '../types/thread-types'; +import { useDispatchActionPromise, useServerCall } from '../utils/action-utils'; + +function useToggleUnreadStatus( + threadInfo: ThreadInfo, + mostRecentNonLocalMessage: ?string, + afterAction: () => void, +): () => void { + const dispatchActionPromise = useDispatchActionPromise(); + const boundSetThreadUnreadStatus: ( + request: SetThreadUnreadStatusRequest, + ) => Promise = useServerCall( + setThreadUnreadStatus, + ); + const toggleUnreadStatus = React.useCallback(() => { + const { unread } = threadInfo.currentUser; + const request = { + threadID: threadInfo.id, + unread: !unread, + latestMessage: mostRecentNonLocalMessage, + }; + dispatchActionPromise( + setThreadUnreadStatusActionTypes, + boundSetThreadUnreadStatus(request), + undefined, + { + threadID: threadInfo.id, + unread: !unread, + }, + ); + afterAction(); + }, [ + threadInfo, + mostRecentNonLocalMessage, + dispatchActionPromise, + afterAction, + boundSetThreadUnreadStatus, + ]); + + return toggleUnreadStatus; +} + +export default useToggleUnreadStatus; diff --git a/web/chat/chat-thread-list-item-menu.react.js b/web/chat/chat-thread-list-item-menu.react.js index 2a0b4c249..ad1074035 100644 --- a/web/chat/chat-thread-list-item-menu.react.js +++ b/web/chat/chat-thread-list-item-menu.react.js @@ -1,94 +1,57 @@ // @flow import classNames from 'classnames'; import * as React from 'react'; -import { - setThreadUnreadStatusActionTypes, - setThreadUnreadStatus, -} from 'lib/actions/activity-actions'; -import type { - SetThreadUnreadStatusPayload, - SetThreadUnreadStatusRequest, -} from 'lib/types/activity-types'; +import useToggleUnreadStatus from 'lib/hooks/toggle-unread-status'; import type { ThreadInfo } from 'lib/types/thread-types'; -import { - useServerCall, - useDispatchActionPromise, -} from 'lib/utils/action-utils'; import SWMansionIcon from '../SWMansionIcon.react'; import css from './chat-thread-list-item-menu.css'; type Props = { +threadInfo: ThreadInfo, +mostRecentNonLocalMessage: ?string, +renderStyle?: 'chat' | 'thread', }; function ChatThreadListItemMenu(props: Props): React.Node { const { renderStyle = 'chat' } = props; const [menuVisible, setMenuVisible] = React.useState(false); const toggleMenu = React.useCallback(() => { setMenuVisible(!menuVisible); }, [menuVisible]); const hideMenu = React.useCallback(() => { setMenuVisible(false); }, []); const { threadInfo, mostRecentNonLocalMessage } = props; - const dispatchActionPromise = useDispatchActionPromise(); - const boundSetThreadUnreadStatus: ( - request: SetThreadUnreadStatusRequest, - ) => Promise = useServerCall( - setThreadUnreadStatus, - ); - const toggleUnreadStatus = React.useCallback(() => { - const { unread } = threadInfo.currentUser; - const request = { - threadID: threadInfo.id, - unread: !unread, - latestMessage: mostRecentNonLocalMessage, - }; - dispatchActionPromise( - setThreadUnreadStatusActionTypes, - boundSetThreadUnreadStatus(request), - undefined, - { - threadID: threadInfo.id, - unread: !unread, - }, - ); - hideMenu(); - }, [ + const toggleUnreadStatus = useToggleUnreadStatus( threadInfo, mostRecentNonLocalMessage, - dispatchActionPromise, hideMenu, - boundSetThreadUnreadStatus, - ]); - + ); const toggleUnreadStatusButtonText = `Mark as ${ threadInfo.currentUser.unread ? 'read' : 'unread' }`; const menuIconSize = renderStyle === 'chat' ? 24 : 16; const btnCls = classNames(css.menuContent, { [css.menuContentVisible]: menuVisible, }); return (
); } export default ChatThreadListItemMenu;