diff --git a/lib/utils/drawer-utils.react.js b/lib/utils/drawer-utils.react.js --- a/lib/utils/drawer-utils.react.js +++ b/lib/utils/drawer-utils.react.js @@ -11,7 +11,7 @@ export type CommunityDrawerItemData = { +threadInfo: ThreadInfo, - +itemChildren?: $ReadOnlyArray>, + +itemChildren: $ReadOnlyArray>, +hasSubchannelsButton: boolean, +labelStyle: T, }; diff --git a/web/sidebar/community-drawer-item-community.react.js b/web/sidebar/community-drawer-item-community.react.js --- a/web/sidebar/community-drawer-item-community.react.js +++ b/web/sidebar/community-drawer-item-community.react.js @@ -3,18 +3,97 @@ import classnames from 'classnames'; import * as React from 'react'; +import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js'; + import css from './community-drawer-item.css'; import type { DrawerItemProps } from './community-drawer-item.react.js'; -import CommunityDrawerItem from './community-drawer-item.react.js'; +import { + getChildren, + getExpandButton, +} from './community-drawer-utils.react.js'; +import ThreadAvatar from '../components/thread-avatar.react.js'; function CommunityDrawerItemCommunity(props: DrawerItemProps): React.Node { + const { + itemData: { threadInfo, itemChildren, hasSubchannelsButton, labelStyle }, + expanded, + toggleExpanded, + paddingLeft, + expandable = true, + handler: Handler, + } = props; + + const children = React.useMemo( + () => + getChildren({ + expanded, + hasSubchannelsButton, + itemChildren, + paddingLeft, + threadInfo, + expandable, + handler: Handler, + }), + [ + expanded, + hasSubchannelsButton, + itemChildren, + paddingLeft, + threadInfo, + expandable, + Handler, + ], + ); + + const itemExpandButton = React.useMemo( + () => + getExpandButton({ + expandable, + childrenLength: itemChildren?.length, + hasSubchannelsButton, + expanded, + }), + [expandable, itemChildren?.length, hasSubchannelsButton, expanded], + ); + + const [handler, setHandler] = React.useState({ + // eslint-disable-next-line no-unused-vars + onClick: event => {}, + isActive: false, + }); + + const onClick = React.useCallback( + (event: SyntheticEvent) => { + toggleExpanded?.(threadInfo.id); + handler.onClick(event); + }, + [threadInfo.id, toggleExpanded, handler], + ); + const classes = classnames({ [css.communityBase]: true, [css.communityExpanded]: props.expanded, }); + + const { uiName } = useResolvedThreadInfo(threadInfo); + const titleLabel = classnames({ + [css[labelStyle]]: true, + [css.activeTitle]: handler.isActive, + }); + + const style = React.useMemo(() => ({ paddingLeft }), [paddingLeft]); + return (
- + + + {itemExpandButton} +
+ +
{uiName}
+
+
+
{children}
); } diff --git a/web/sidebar/community-drawer-item.css b/web/sidebar/community-drawer-item.css --- a/web/sidebar/community-drawer-item.css +++ b/web/sidebar/community-drawer-item.css @@ -46,7 +46,7 @@ } .communityBase { - padding-top: 2px; + padding-top: 4px; padding-bottom: 2px; padding-right: 4px; overflow: hidden; @@ -56,7 +56,6 @@ background-color: var(--drawer-open-community-bg); border-top-right-radius: 8px; border-bottom-right-radius: 8px; - padding-top: 4px; padding-bottom: 4px; } diff --git a/web/sidebar/community-drawer-item.react.js b/web/sidebar/community-drawer-item.react.js --- a/web/sidebar/community-drawer-item.react.js +++ b/web/sidebar/community-drawer-item.react.js @@ -8,8 +8,10 @@ import type { HandlerProps } from './community-drawer-item-handlers.react.js'; import css from './community-drawer-item.css'; -import { ExpandButton } from './expand-buttons.react.js'; -import SubchannelsButton from './subchannels-button.react.js'; +import { + getChildren, + getExpandButton, +} from './community-drawer-utils.react.js'; import ThreadAvatar from '../components/thread-avatar.react.js'; import { shouldRenderAvatars } from '../utils/avatar-utils.js'; @@ -22,9 +24,6 @@ +handler: React.ComponentType, }; -const indentation = 14; -const subchannelsButtonIndentation = 24; - function CommunityDrawerItem(props: DrawerItemProps): React.Node { const { itemData: { threadInfo, itemChildren, hasSubchannelsButton, labelStyle }, @@ -35,71 +34,50 @@ handler: Handler, } = props; - const children = React.useMemo(() => { - if (!expanded) { - return null; - } - if (hasSubchannelsButton) { - const buttonPaddingLeft = paddingLeft + subchannelsButtonIndentation; - return ( -
- -
- ); - } - if (!itemChildren) { - return null; - } - return itemChildren.map(item => ( - - )); - }, [ - expanded, - hasSubchannelsButton, - itemChildren, - paddingLeft, - threadInfo, - expandable, - Handler, - ]); + const children = React.useMemo( + () => + getChildren({ + expanded, + hasSubchannelsButton, + itemChildren, + paddingLeft, + threadInfo, + expandable, + handler: Handler, + }), + [ + expanded, + hasSubchannelsButton, + itemChildren, + paddingLeft, + threadInfo, + expandable, + Handler, + ], + ); const onExpandToggled = React.useCallback( () => (toggleExpanded ? toggleExpanded(threadInfo.id) : null), [toggleExpanded, threadInfo.id], ); - const itemExpandButton = React.useMemo(() => { - if (!expandable) { - return null; - } - if (itemChildren?.length === 0 && !hasSubchannelsButton) { - return ( -
- -
- ); - } - return ( -
- -
- ); - }, [ - expandable, - itemChildren?.length, - hasSubchannelsButton, - onExpandToggled, - expanded, - ]); + const itemExpandButton = React.useMemo( + () => + getExpandButton({ + expandable, + childrenLength: itemChildren.length, + hasSubchannelsButton, + onExpandToggled, + expanded, + }), + [ + expandable, + itemChildren.length, + hasSubchannelsButton, + onExpandToggled, + expanded, + ], + ); const [handler, setHandler] = React.useState({ // eslint-disable-next-line no-unused-vars @@ -174,4 +152,4 @@ const MemoizedCommunityDrawerItem: React.ComponentType = React.memo(CommunityDrawerItem); -export default MemoizedCommunityDrawerItem; +export default MemoizedCommunityDrawerItemChat; diff --git a/web/sidebar/community-drawer-utils.react.js b/web/sidebar/community-drawer-utils.react.js new file mode 100644 --- /dev/null +++ b/web/sidebar/community-drawer-utils.react.js @@ -0,0 +1,89 @@ +// @flow + +import * as React from 'react'; + +import type { ThreadInfo } from 'lib/types/thread-types'; +import type { CommunityDrawerItemData } from 'lib/utils/drawer-utils.react'; + +import type { HandlerProps } from './community-drawer-item-handlers.react'; +import css from './community-drawer-item.css'; +import CommunityDrawerItemChat from './community-drawer-item.react.js'; +import { ExpandButton } from './expand-buttons.react.js'; +import SubchannelsButton from './subchannels-button.react.js'; + +const indentation = 14; +const subchannelsButtonIndentation = 24; + +function getChildren({ + expanded, + hasSubchannelsButton, + itemChildren, + paddingLeft, + threadInfo, + expandable, + handler, +}: { + expanded: boolean, + hasSubchannelsButton: boolean, + itemChildren: $ReadOnlyArray>, + paddingLeft: number, + threadInfo: ThreadInfo, + expandable: boolean, + handler: React.ComponentType, +}): React.Node { + if (!expanded) { + return null; + } + if (hasSubchannelsButton) { + const buttonPaddingLeft = paddingLeft + subchannelsButtonIndentation; + return ( +
+ +
+ ); + } + return itemChildren.map(item => ( + + )); +} + +function getExpandButton({ + expandable, + childrenLength, + hasSubchannelsButton, + onExpandToggled, + expanded, +}: { + +expandable: boolean, + +childrenLength: ?number, + +hasSubchannelsButton: boolean, + +onExpandToggled?: ?() => ?void, + +expanded: boolean, +}): React.Node { + if (!expandable) { + return null; + } + if (childrenLength === 0 && !hasSubchannelsButton) { + return ( +
+ +
+ ); + } + return ( +
+ +
+ ); +} + +export { getChildren, getExpandButton }; diff --git a/web/sidebar/expand-buttons.react.js b/web/sidebar/expand-buttons.react.js --- a/web/sidebar/expand-buttons.react.js +++ b/web/sidebar/expand-buttons.react.js @@ -9,7 +9,7 @@ import Button from '../components/button.react.js'; type Props = { - +onClick?: () => mixed, + +onClick?: ?() => mixed, +expanded?: boolean, +disabled?: boolean, };