diff --git a/web/sidebar/community-drawer-item-community-handlers.react.js b/web/sidebar/community-drawer-item-community-handlers.react.js new file mode 100644 --- /dev/null +++ b/web/sidebar/community-drawer-item-community-handlers.react.js @@ -0,0 +1,116 @@ +// @flow + +import * as React from 'react'; +import { useDispatch } from 'react-redux'; + +import { + updateCalendarCommunityFilter, + updateChatCommunityFilter, + clearChatCommunityFilter, +} from 'lib/actions/community-actions.js'; +import type { ThreadInfo } from 'lib/types/thread-types.js'; + +import type { CommunityDrawerItemCommunityHandler } from './community-drawer-item-handler.react.js'; +import { useSelector } from '../redux/redux-utils.js'; +import { useCommunityIsPickedCalendar } from '../selectors/calendar-selectors.js'; +import { + useOnClickThread, + useThreadIsActive, +} from '../selectors/thread-selectors.js'; +import type { NavigationTab } from '../types/nav-types.js'; + +export type HandlerProps = { + +setHandler: (handler: CommunityDrawerItemCommunityHandler) => void, + +threadInfo: ThreadInfo, +}; + +function ChatDrawerItemCommunityHandler(props: HandlerProps): React.Node { + const { setHandler, threadInfo } = props; + const onClickThread = useOnClickThread(threadInfo); + const isActive = useThreadIsActive(threadInfo.id); + const dispatch = useDispatch(); + + const openCommunityID = useSelector(state => state.communityPickerStore.chat); + + const expanded = openCommunityID === threadInfo.id; + + const onClick = React.useCallback( + (event: SyntheticEvent) => { + if (!isActive) { + onClickThread(event); + } + if (openCommunityID === threadInfo.id && isActive) { + dispatch({ + type: clearChatCommunityFilter, + }); + return; + } + const community = threadInfo.community ?? threadInfo.id; + dispatch({ + type: updateChatCommunityFilter, + payload: community, + }); + }, + [ + dispatch, + isActive, + onClickThread, + openCommunityID, + threadInfo.community, + threadInfo.id, + ], + ); + + const handler = React.useMemo( + () => ({ onClick, isActive, expanded }), + [expanded, isActive, onClick], + ); + React.useEffect(() => { + setHandler(handler); + }, [handler, setHandler]); + + return null; +} + +function CalendarDrawerItemCommunityHandler(props: HandlerProps): React.Node { + const { setHandler, threadInfo } = props; + const dispatch = useDispatch(); + + const onClick = React.useCallback(() => { + dispatch({ + type: updateCalendarCommunityFilter, + payload: threadInfo.id, + }); + }, [dispatch, threadInfo.id]); + + const isActive = useCommunityIsPickedCalendar(threadInfo.id); + + const expanded = false; + + const handler = React.useMemo( + () => ({ onClick, isActive, expanded }), + [onClick, isActive, expanded], + ); + React.useEffect(() => { + setHandler(handler); + }, [handler, setHandler]); + + return null; +} + +const communityDrawerItemCommunityHandlers: { + +[tab: NavigationTab]: React.ComponentType, +} = Object.freeze({ + chat: ChatDrawerItemCommunityHandler, + calendar: CalendarDrawerItemCommunityHandler, +}); + +function getCommunityDrawerItemCommunityHandler( + tab: NavigationTab, +): React.ComponentType { + return ( + communityDrawerItemCommunityHandlers[tab] ?? ChatDrawerItemCommunityHandler + ); +} + +export { getCommunityDrawerItemCommunityHandler }; diff --git a/web/sidebar/community-drawer-item-handler.react.js b/web/sidebar/community-drawer-item-handler.react.js --- a/web/sidebar/community-drawer-item-handler.react.js +++ b/web/sidebar/community-drawer-item-handler.react.js @@ -4,3 +4,9 @@ +onClick: (event: SyntheticEvent) => void, +isActive: boolean, }; + +export type CommunityDrawerItemCommunityHandler = { + +onClick: (event: SyntheticEvent) => void, + +expanded: boolean, + +isActive: boolean, +};