Changeset View
Changeset View
Standalone View
Standalone View
web/sidebar/community-drawer-item.react.js
// @flow | // @flow | ||||
import classnames from 'classnames'; | import classnames from 'classnames'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import type { CommunityDrawerItemData } from 'lib/utils/drawer-utils.react.js'; | import type { CommunityDrawerItemData } from 'lib/utils/drawer-utils.react.js'; | ||||
import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js'; | import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js'; | ||||
import type { HandlerProps } from './community-drawer-item-handlers.react.js'; | import type { HandlerProps } from './community-drawer-item-handlers.react.js'; | ||||
import css from './community-drawer-item.css'; | import css from './community-drawer-item.css'; | ||||
import { ExpandButton } from './expand-buttons.react.js'; | import { | ||||
import SubchannelsButton from './subchannels-button.react.js'; | getChildren, | ||||
getExpandButton, | |||||
} from './community-drawer-utils.react.js'; | |||||
export type DrawerItemProps = { | export type DrawerItemProps = { | ||||
+itemData: CommunityDrawerItemData<string>, | +itemData: CommunityDrawerItemData<string>, | ||||
+toggleExpanded?: (threadID: string) => void, | +toggleExpanded?: (threadID: string) => void, | ||||
+expanded: boolean, | +expanded: boolean, | ||||
+paddingLeft: number, | +paddingLeft: number, | ||||
+expandable?: boolean, | +expandable?: boolean, | ||||
+handler: React.ComponentType<HandlerProps>, | +handler: React.ComponentType<HandlerProps>, | ||||
}; | }; | ||||
const indentation = 14; | |||||
const subchannelsButtonIndentation = 24; | |||||
function CommunityDrawerItem(props: DrawerItemProps): React.Node { | function CommunityDrawerItem(props: DrawerItemProps): React.Node { | ||||
const { | const { | ||||
itemData: { threadInfo, itemChildren, hasSubchannelsButton, labelStyle }, | itemData: { threadInfo, itemChildren, hasSubchannelsButton, labelStyle }, | ||||
expanded, | expanded, | ||||
toggleExpanded, | toggleExpanded, | ||||
paddingLeft, | paddingLeft, | ||||
expandable = true, | expandable = true, | ||||
handler: Handler, | handler: Handler, | ||||
} = props; | } = props; | ||||
const children = React.useMemo(() => { | const children = React.useMemo( | ||||
if (!expanded) { | () => | ||||
return null; | getChildren( | ||||
} | expanded, | ||||
if (hasSubchannelsButton) { | hasSubchannelsButton, | ||||
const buttonPaddingLeft = paddingLeft + subchannelsButtonIndentation; | itemChildren, | ||||
return ( | paddingLeft, | ||||
<div | threadInfo, | ||||
className={css.subchannelsButton} | expandable, | ||||
style={{ paddingLeft: buttonPaddingLeft }} | Handler, | ||||
> | ), | ||||
<SubchannelsButton threadInfo={threadInfo} /> | [ | ||||
</div> | |||||
); | |||||
} | |||||
if (!itemChildren) { | |||||
return null; | |||||
} | |||||
return itemChildren.map(item => ( | |||||
<MemoizedCommunityDrawerItemChat | |||||
itemData={item} | |||||
key={item.threadInfo.id} | |||||
paddingLeft={paddingLeft + indentation} | |||||
expandable={expandable} | |||||
handler={Handler} | |||||
/> | |||||
)); | |||||
}, [ | |||||
expanded, | expanded, | ||||
hasSubchannelsButton, | hasSubchannelsButton, | ||||
itemChildren, | itemChildren, | ||||
paddingLeft, | paddingLeft, | ||||
threadInfo, | threadInfo, | ||||
expandable, | expandable, | ||||
Handler, | Handler, | ||||
]); | ], | ||||
); | |||||
const onExpandToggled = React.useCallback( | const onExpandToggled = React.useCallback( | ||||
() => (toggleExpanded ? toggleExpanded(threadInfo.id) : null), | () => (toggleExpanded ? toggleExpanded(threadInfo.id) : null), | ||||
[toggleExpanded, threadInfo.id], | [toggleExpanded, threadInfo.id], | ||||
); | ); | ||||
const itemExpandButton = React.useMemo(() => { | const itemExpandButton = React.useMemo( | ||||
if (!expandable) { | () => | ||||
return null; | getExpandButton( | ||||
} | |||||
if (itemChildren?.length === 0 && !hasSubchannelsButton) { | |||||
return ( | |||||
<div className={css.buttonContainer}> | |||||
<ExpandButton disabled={true} /> | |||||
</div> | |||||
); | |||||
} | |||||
return ( | |||||
<div className={css.buttonContainer}> | |||||
<ExpandButton onClick={onExpandToggled} expanded={expanded} /> | |||||
</div> | |||||
); | |||||
}, [ | |||||
expandable, | expandable, | ||||
itemChildren?.length, | itemChildren?.length, | ||||
hasSubchannelsButton, | hasSubchannelsButton, | ||||
onExpandToggled, | onExpandToggled, | ||||
expanded, | expanded, | ||||
]); | ), | ||||
[ | |||||
expandable, | |||||
itemChildren?.length, | |||||
hasSubchannelsButton, | |||||
onExpandToggled, | |||||
expanded, | |||||
], | |||||
); | |||||
const [handler, setHandler] = React.useState({ | const [handler, setHandler] = React.useState({ | ||||
// eslint-disable-next-line no-unused-vars | // eslint-disable-next-line no-unused-vars | ||||
onClick: event => {}, | onClick: event => {}, | ||||
}); | }); | ||||
const { uiName } = useResolvedThreadInfo(threadInfo); | const { uiName } = useResolvedThreadInfo(threadInfo); | ||||
const titleLabel = classnames({ | const titleLabel = classnames({ | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
const MemoizedCommunityDrawerItemChat: React.ComponentType<CommunityDrawerItemChatProps> = | const MemoizedCommunityDrawerItemChat: React.ComponentType<CommunityDrawerItemChatProps> = | ||||
React.memo(CommunityDrawerItemChat); | React.memo(CommunityDrawerItemChat); | ||||
const MemoizedCommunityDrawerItem: React.ComponentType<DrawerItemProps> = | const MemoizedCommunityDrawerItem: React.ComponentType<DrawerItemProps> = | ||||
React.memo(CommunityDrawerItem); | React.memo(CommunityDrawerItem); | ||||
export default MemoizedCommunityDrawerItem; | export default MemoizedCommunityDrawerItemChat; |