Skip to content

Commit

Permalink
Give items in repl history stable indexes to fix race when updating i…
Browse files Browse the repository at this point in the history
…tem heights (#397)
  • Loading branch information
jaclarke authored Jan 7, 2025
1 parent 1e292e2 commit b17f774
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 25 deletions.
23 changes: 16 additions & 7 deletions shared/studio/tabs/repl/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,16 +171,22 @@ const ReplList = observer(function ReplList({

setRenderHeader(scrollTop < headerHeight + 100);

const historyCount = replState.itemHeights.historyCount;

const startIndex = Math.max(
0,
replState.itemHeights.getIndexAtHeight(
Math.max(0, scrollTop - headerHeight)
) - 2
) +
historyCount -
2
);
const endIndex = Math.min(
replState.itemHeights.getIndexAtHeight(
Math.max(0, scrollTop - headerHeight + ref.current!.clientHeight)
) + 2,
) +
historyCount +
2,
replState.queryHistory.length - 1
);

Expand All @@ -191,7 +197,9 @@ const ReplList = observer(function ReplList({
startIndex,
endIndex,
old[0] !== startIndex
? replState.itemHeights.getHeightAtIndex(startIndex)
? replState.itemHeights.getHeightAtIndex(
startIndex - historyCount
)
: old[2],
]
);
Expand All @@ -217,14 +225,15 @@ const ReplList = observer(function ReplList({

const items: JSX.Element[] = [];
if (replState.queryHistory.length) {
const historyCount = replState.itemHeights.historyCount;
let top = visibleBounds[2] + headerHeight;
for (let i = visibleBounds[0]; i <= visibleBounds[1]; i++) {
const item = replState.queryHistory[i];
items.push(
<ReplHistoryItem
key={item.$modelId}
state={replState}
index={i}
historyIndex={i - historyCount}
item={item}
styleTop={top}
dbName={dbState.name}
Expand Down Expand Up @@ -589,13 +598,13 @@ const ResultGridWrapper = observer(function ResultGridWrapper({

const ReplHistoryItem = observer(function ReplHistoryItem({
state,
index,
historyIndex,
item,
styleTop,
dbName,
}: {
state: Repl;
index: number;
historyIndex: number;
item: ReplHistoryItemState;
styleTop: number;
dbName: string;
Expand Down Expand Up @@ -663,7 +672,7 @@ const ReplHistoryItem = observer(function ReplHistoryItem({
updateScroll.current = false;
}
item.renderHeight = paddedHeight;
state.itemHeights.updateItemHeight(index, paddedHeight);
state.itemHeights.updateItemHeight(historyIndex, paddedHeight);
}
},
[item.showDateHeader]
Expand Down
37 changes: 19 additions & 18 deletions shared/studio/tabs/repl/state/itemHeights.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ export class ItemHeights {
return this._totalHeight.get();
}

get historyCount() {
return this._history._length;
}

private _updateTotalHeight() {
runInAction(() =>
this._totalHeight.set(
Expand All @@ -30,41 +34,38 @@ export class ItemHeights {
this._updateTotalHeight();
}

// to ensure stable item indexes:
// positive indexes are current items starting at 0
// negative indexes are history items starting at -1

updateItemHeight(index: number, height: number) {
if (index < this._history._length) {
this._history.updateHeight(this._history._length - index - 1, height);
if (index < 0) {
this._history.updateHeight(-1 - index, height);
} else {
this._current.updateHeight(index - this._history._length, height);
this._current.updateHeight(index, height);
}
this._updateTotalHeight();
}

getIndexAtHeight(height: number) {
if (height < this._history._root.total) {
return (
this._history._length -
this._history.getIndexAtHeight(this._history._root.total - height) -
1
-this._history.getIndexAtHeight(this._history._root.total - height) - 1
);
} else {
return (
this._current.getIndexAtHeight(height - this._history._root.total) +
this._history._length
return this._current.getIndexAtHeight(
height - this._history._root.total
);
}
}

getHeightAtIndex(index: number) {
if (index < this._history._length) {
return index
? this._history._root.total -
this._history.getHeightAtIndex(this._history._length - index)
: 0;
if (index < 0) {
return -index >= this._history._length
? 0
: this._history._root.total - this._history.getHeightAtIndex(-index);
} else {
return (
this._history._root.total +
this._current.getHeightAtIndex(index - this._history._length)
);
return this._history._root.total + this._current.getHeightAtIndex(index);
}
}
}
Expand Down

0 comments on commit b17f774

Please sign in to comment.