Changeset View
Changeset View
Standalone View
Standalone View
web/navigation-panels/nav-state-info-bar.react.js
// @flow | // @flow | ||||
import classnames from 'classnames'; | |||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import type { ThreadInfo } from 'lib/types/thread-types.js'; | import type { ThreadInfo } from 'lib/types/thread-types.js'; | ||||
import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js'; | import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js'; | ||||
import ThreadAncestors from './chat-thread-ancestors.react.js'; | import ThreadAncestors from './chat-thread-ancestors.react.js'; | ||||
import css from './nav-state-info-bar.css'; | import css from './nav-state-info-bar.css'; | ||||
type NavStateInfoBarProps = { | type NavStateInfoBarProps = { | ||||
+threadInfo: ThreadInfo, | +threadInfo: ThreadInfo, | ||||
}; | }; | ||||
function NavStateInfoBar(props: NavStateInfoBarProps): React.Node { | function NavStateInfoBar(props: NavStateInfoBarProps): React.Node { | ||||
const { threadInfo } = props; | const { threadInfo } = props; | ||||
const threadBackgroundColorStyle = React.useMemo( | const threadBackgroundColorStyle = React.useMemo( | ||||
() => ({ | () => ({ | ||||
background: `#${threadInfo.color}`, | background: `#${threadInfo.color}`, | ||||
}), | }), | ||||
[threadInfo.color], | [threadInfo.color], | ||||
); | ); | ||||
const { uiName } = useResolvedThreadInfo(threadInfo); | const { uiName } = useResolvedThreadInfo(threadInfo); | ||||
return ( | return ( | ||||
<div className={css.topBarContainer}> | <> | ||||
<div className={css.topBarThreadInfo}> | <div className={css.topBarThreadInfo}> | ||||
<div | <div | ||||
className={css.threadColorSquare} | className={css.threadColorSquare} | ||||
style={threadBackgroundColorStyle} | style={threadBackgroundColorStyle} | ||||
/> | /> | ||||
<p className={css.threadTitle}>{uiName}</p> | <p className={css.threadTitle}>{uiName}</p> | ||||
<ThreadAncestors threadInfo={threadInfo} /> | <ThreadAncestors threadInfo={threadInfo} /> | ||||
</div> | </div> | ||||
</div> | </> | ||||
); | ); | ||||
} | } | ||||
export default NavStateInfoBar; | type PossiblyEmptyNavStateInfoBarProps = { | ||||
+threadInfoInput: ?ThreadInfo, | |||||
}; | |||||
function PossiblyEmptyNavStateInfoBar( | |||||
props: PossiblyEmptyNavStateInfoBarProps, | |||||
): React.Node { | |||||
const { threadInfoInput } = props; | |||||
const [threadInfo, setThreadInfo] = React.useState(threadInfoInput); | |||||
React.useEffect(() => { | |||||
if (threadInfoInput !== threadInfo) { | |||||
if (threadInfoInput) { | |||||
setThreadInfo(threadInfoInput); | |||||
} else { | |||||
const timeout = setTimeout(() => { | |||||
setThreadInfo(null); | |||||
}, 200); | |||||
return () => clearTimeout(timeout); | |||||
} | |||||
} | |||||
}, [threadInfoInput, threadInfo]); | |||||
const content = React.useMemo(() => { | |||||
if (threadInfo) { | |||||
return <NavStateInfoBar threadInfo={threadInfo} />; | |||||
} else { | |||||
return null; | |||||
} | |||||
}, [threadInfo]); | |||||
const classes = classnames(css.topBarContainer, { | |||||
[css.hide]: !threadInfoInput, | |||||
[css.show]: threadInfoInput, | |||||
}); | |||||
return <div className={classes}>{content}</div>; | |||||
} | |||||
export default PossiblyEmptyNavStateInfoBar; |