Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,29 @@ function SuspenseRects({
});
}

function handleDoubleClick(event: SyntheticMouseEvent) {
if (event.defaultPrevented) {
// Already clicked on an inner rect
return;
}
event.preventDefault();
suspenseTreeDispatch({
type: 'TOGGLE_TIMELINE_FOR_ID',
payload: suspenseID,
});
}

function handlePointerOver(event: SyntheticPointerEvent) {
if (event.defaultPrevented) {
// Already hovered an inner rect
return;
}
event.preventDefault();
highlightHostInstance(suspenseID);
suspenseTreeDispatch({
type: 'HOVER_TIMELINE_FOR_ID',
payload: suspenseID,
});
}

function handlePointerLeave(event: SyntheticPointerEvent) {
Expand All @@ -114,6 +130,10 @@ function SuspenseRects({
}
event.preventDefault();
clearHighlightHostInstance();
suspenseTreeDispatch({
type: 'HOVER_TIMELINE_FOR_ID',
payload: -1,
});
}

// TODO: Use the nearest Suspense boundary
Expand All @@ -137,6 +157,7 @@ function SuspenseRects({
rect={rect}
data-highlighted={selected}
onClick={handleClick}
onDoubleClick={handleDoubleClick}
onPointerOver={handlePointerOver}
onPointerLeave={handlePointerLeave}
// Reach-UI tooltip will go out of bounds of parent scroll container.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
background: var(--color-background-selected);
}

.SuspenseScrubberStepHighlight > .SuspenseScrubberBead,
.SuspenseScrubberStepHighlight > .SuspenseScrubberBeadSelected,
.SuspenseScrubberStep:hover > .SuspenseScrubberBead,
.SuspenseScrubberStep:hover > .SuspenseScrubberBeadSelected {
height: 0.75rem;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default function SuspenseScrubber({
min,
max,
value,
highlight,
onBlur,
onChange,
onFocus,
Expand All @@ -27,6 +28,7 @@ export default function SuspenseScrubber({
min: number,
max: number,
value: number,
highlight: number,
onBlur: () => void,
onChange: (index: number) => void,
onFocus: () => void,
Expand All @@ -53,7 +55,12 @@ export default function SuspenseScrubber({
steps.push(
<div
key={index}
className={styles.SuspenseScrubberStep}
className={
styles.SuspenseScrubberStep +
(highlight === index
? ' ' + styles.SuspenseScrubberStepHighlight
: '')
}
onPointerDown={handlePress.bind(null, index)}
onMouseEnter={onHoverSegment.bind(null, index)}>
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ function SuspenseTimelineInput() {
selectedRootID: rootID,
timeline,
timelineIndex,
hoveredTimelineIndex,
playing,
} = useContext(SuspenseTreeStateContext);

Expand Down Expand Up @@ -202,6 +203,7 @@ function SuspenseTimelineInput() {
min={min}
max={max}
value={timelineIndex}
highlight={hoveredTimelineIndex}
onBlur={handleBlur}
onChange={handleChange}
onFocus={handleFocus}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export type SuspenseTreeState = {
selectedSuspenseID: SuspenseNode['id'] | null,
timeline: $ReadOnlyArray<SuspenseNode['id']>,
timelineIndex: number | -1,
hoveredTimelineIndex: number | -1,
uniqueSuspendersOnly: boolean,
playing: boolean,
};
Expand Down Expand Up @@ -72,6 +73,14 @@ type ACTION_SUSPENSE_PLAY_PAUSE = {
type ACTION_SUSPENSE_PLAY_TICK = {
type: 'SUSPENSE_PLAY_TICK',
};
type ACTION_TOGGLE_TIMELINE_FOR_ID = {
type: 'TOGGLE_TIMELINE_FOR_ID',
payload: SuspenseNode['id'],
};
type ACTION_HOVER_TIMELINE_FOR_ID = {
type: 'HOVER_TIMELINE_FOR_ID',
payload: SuspenseNode['id'],
};

export type SuspenseTreeAction =
| ACTION_SUSPENSE_TREE_MUTATION
Expand All @@ -81,7 +90,9 @@ export type SuspenseTreeAction =
| ACTION_SUSPENSE_SET_TIMELINE_INDEX
| ACTION_SUSPENSE_SKIP_TIMELINE_INDEX
| ACTION_SUSPENSE_PLAY_PAUSE
| ACTION_SUSPENSE_PLAY_TICK;
| ACTION_SUSPENSE_PLAY_TICK
| ACTION_TOGGLE_TIMELINE_FOR_ID
| ACTION_HOVER_TIMELINE_FOR_ID;
export type SuspenseTreeDispatch = (action: SuspenseTreeAction) => void;

const SuspenseTreeStateContext: ReactContext<SuspenseTreeState> =
Expand Down Expand Up @@ -122,6 +133,7 @@ function getInitialState(store: Store): SuspenseTreeState {
selectedRootID,
timeline: [],
timelineIndex: -1,
hoveredTimelineIndex: -1,
uniqueSuspendersOnly,
playing: false,
};
Expand All @@ -144,6 +156,7 @@ function getInitialState(store: Store): SuspenseTreeState {
selectedRootID,
timeline,
timelineIndex,
hoveredTimelineIndex: -1,
uniqueSuspendersOnly,
playing: false,
};
Expand Down Expand Up @@ -397,6 +410,47 @@ function SuspenseTreeContextController({children}: Props): React.Node {
playing: nextPlaying,
};
}
case 'TOGGLE_TIMELINE_FOR_ID': {
const suspenseID = action.payload;
const timelineIndexForSuspenseID =
state.timeline.indexOf(suspenseID);
if (timelineIndexForSuspenseID === -1) {
// This boundary is no longer in the timeline.
return state;
}
const nextTimelineIndex =
timelineIndexForSuspenseID === 0
? // For roots, there's no toggling. It's always just jump to beginning.
0
: // For boundaries, we'll either jump to before or after its reveal depending
// on if we're currently displaying it or not according to the timeline.
state.timelineIndex < timelineIndexForSuspenseID
? // We're currently before this suspense boundary has been revealed so we
// should jump ahead to reveal it.
timelineIndexForSuspenseID
: // Otherwise, if we're currently showing it, jump to right before to hide it.
timelineIndexForSuspenseID - 1;
const nextSelectedSuspenseID = state.timeline[nextTimelineIndex];
const nextLineage = store.getSuspenseLineage(
nextSelectedSuspenseID,
);
return {
...state,
lineage: nextLineage,
selectedSuspenseID: nextSelectedSuspenseID,
timelineIndex: nextTimelineIndex,
playing: false, // pause
};
}
case 'HOVER_TIMELINE_FOR_ID': {
const suspenseID = action.payload;
const timelineIndexForSuspenseID =
state.timeline.indexOf(suspenseID);
return {
...state,
hoveredTimelineIndex: timelineIndexForSuspenseID,
};
}
default:
throw new Error(`Unrecognized action "${action.type}"`);
}
Expand Down
Loading