import * as React from 'react';
import {Fragment, useContext, useEffect, useRef} from 'react';
import WhatChanged from './WhatChanged';
import {ProfilerContext} from './ProfilerContext';
import {formatDuration, formatTime} from './utils';
import {StoreContext} from '../context';
import Button from '../Button';
import ButtonIcon from '../ButtonIcon';
import InspectedElementBadges from '../Components/InspectedElementBadges';
import styles from './SidebarSelectedFiberInfo.css';
export default function SidebarSelectedFiberInfo(): React.Node {
const {profilerStore} = useContext(StoreContext);
const {
rootID,
selectCommitIndex,
selectedCommitIndex,
selectedFiberID,
selectedFiberName,
selectFiber,
} = useContext(ProfilerContext);
const {profilingCache} = profilerStore;
const selectedListItemRef = useRef<HTMLElement | null>(null);
useEffect(() => {
const selectedElement = selectedListItemRef.current;
if (
selectedElement !== null &&
typeof selectedElement.scrollIntoView === 'function'
) {
selectedElement.scrollIntoView({block: 'nearest', inline: 'nearest'});
}
}, [selectedCommitIndex]);
if (
selectedFiberID === null ||
rootID === null ||
selectedCommitIndex === null
) {
return null;
}
const commitIndices = profilingCache.getFiberCommits({
fiberID: selectedFiberID,
rootID: rootID,
});
const {nodes} = profilingCache.getCommitTree({
rootID,
commitIndex: selectedCommitIndex,
});
const node = nodes.get(selectedFiberID);
const handleKeyDown = event => {
switch (event.key) {
case 'ArrowUp':
if (selectedCommitIndex !== null) {
const prevIndex = commitIndices.indexOf(selectedCommitIndex);
const nextIndex =
prevIndex > 0 ? prevIndex - 1 : commitIndices.length - 1;
selectCommitIndex(commitIndices[nextIndex]);
}
event.preventDefault();
break;
case 'ArrowDown':
if (selectedCommitIndex !== null) {
const prevIndex = commitIndices.indexOf(selectedCommitIndex);
const nextIndex =
prevIndex < commitIndices.length - 1 ? prevIndex + 1 : 0;
selectCommitIndex(commitIndices[nextIndex]);
}
event.preventDefault();
break;
default:
break;
}
};
const listItems = [];
let i = 0;
for (i = 0; i < commitIndices.length; i++) {
const commitIndex = commitIndices[i];
const {duration, timestamp} = profilerStore.getCommitData(
((rootID: any): number),
commitIndex,
);
listItems.push(
<button
key={commitIndex}
ref={selectedCommitIndex === commitIndex ? selectedListItemRef : null}
className={
selectedCommitIndex === commitIndex
? styles.CurrentCommit
: styles.Commit
}
onClick={() => selectCommitIndex(commitIndex)}>
{formatTime(timestamp)}s for {formatDuration(duration)}ms
</button>,
);
}
return (
<Fragment>
<div className={styles.Toolbar}>
<div className={styles.Component}>
{selectedFiberName || 'Selected component'}
</div>
<Button
onClick={() => selectFiber(null, null)}
title="Back to commit view">
<ButtonIcon type="close" />
</Button>
</div>
<div className={styles.Content} onKeyDown={handleKeyDown} tabIndex={0}>
{node != null && (
<InspectedElementBadges
hocDisplayNames={node.hocDisplayNames}
compiledWithForget={node.compiledWithForget}
/>
)}
<WhatChanged fiberID={((selectedFiberID: any): number)} />
{listItems.length > 0 && (
<div>
<label className={styles.Label}>Rendered at: </label>
{listItems}
</div>
)}
{listItems.length === 0 && (
<div>Did not render on the client during this profiling session.</div>
)}
</div>
</Fragment>
);
}