Skip to content

Commit

Permalink
fix: fix rendererd visible items for no useRecycle
Browse files Browse the repository at this point in the history
  • Loading branch information
daybrush committed Jun 19, 2024
1 parent db56823 commit 92d7e93
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 3 deletions.
90 changes: 88 additions & 2 deletions packages/infinitegrid/src/Infinite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,79 @@ export class Infinite extends Component<InfiniteEvents> {
}
}

/**
* Visible item area according to scrollPos
* @param scrollPos
*/
public getVisibleArea(scrollPos: number): {
start: number;
end: number;
direction?: "end" | "start";
hasVirtualItems?: boolean;
isStart?: boolean;
isEnd?: boolean;
nextVisibleItems?: InfiniteItem[];
} {
const prevStartCursor = this.startCursor;
const prevEndCursor = this.endCursor;
const items = this.items;
const length = items.length;
const size = this.size;
const {
defaultDirection,
threshold,
} = this.options;
const isDirectionEnd = defaultDirection === "end";

if (!length) {
// no items
return {
start: -1,
end: -1,
direction: isDirectionEnd ? "end" : "start",
};
} else if (prevStartCursor === -1 || prevEndCursor === -1) {
const nextCursor = isDirectionEnd ? 0 : length - 1;

return {
start: nextCursor,
end: nextCursor,
direction: isDirectionEnd ? "end" : "start",
};
}

const endScrollPos = scrollPos + size;
const visibles = items.map((item) => {
const {
startOutline,
endOutline,
} = item;

if (!startOutline.length || !endOutline.length || isFlatOutline(startOutline, endOutline)) {
return false;
}
const startPos = Math.min(...startOutline);
const endPos = Math.max(...endOutline);

if (startPos - threshold <= endScrollPos && scrollPos <= endPos + threshold) {
return true;
}
return false;
});
let nextStartCursor = visibles.indexOf(true);
let nextEndCursor = visibles.lastIndexOf(true);

if (nextStartCursor === -1) {
nextStartCursor = prevStartCursor;
nextEndCursor = prevEndCursor;
}

return {
start: nextStartCursor,
end: nextEndCursor,
};
}

/**
* Call the requestAppend or requestPrepend event to fill the virtual items.
* @ko virtual item을 채우기 위해 requestAppend 또는 requestPrepend 이벤트를 호출합니다.
Expand Down Expand Up @@ -374,8 +447,21 @@ export class Infinite extends Component<InfiniteEvents> {
public getItemByKey(key: string | number) {
return this.itemKeys[key];
}
public getRenderedVisibleItems() {
const items = this.getVisibleItems();
/**
*
* @param scrollPos
* @returns
*/
public getRenderedVisibleItems(scrollPos?: number) {
let items = this.getVisibleItems();

if (!this.options.useRecycle && scrollPos != null) {
const area = this.getVisibleArea(scrollPos);

if (area.start > -1) {
items = this.items.slice(area.start, area.end + 1);
}
}
const rendered = items.map(({ startOutline, endOutline }) => {
const length = startOutline.length;

Expand Down
2 changes: 1 addition & 1 deletion packages/infinitegrid/src/InfiniteGrid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -866,7 +866,7 @@ class InfiniteGrid<Options extends InfiniteGridOptions = InfiniteGridOptions> ex

private _onRenderComplete = ({ isResize, mounted, updated, direction }: OnPickedRenderComplete): void => {
const infinite = this.infinite;
const prevRenderedGroups = infinite.getRenderedVisibleItems();
const prevRenderedGroups = infinite.getRenderedVisibleItems(this.scrollManager.getScrollPos()!);
const length = prevRenderedGroups.length;
const isDirectionEnd = direction === DIRECTION.END;

Expand Down
50 changes: 50 additions & 0 deletions packages/infinitegrid/test/unit/Infinite.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,56 @@ describe("test Infinite", () => {
expect(items2.map((item) => item.key)).to.be.deep.equals([1, 2]);
expect(items3.map((item) => item.key)).to.be.deep.equals([2, 3]);
});
it("should check whether rendered visible items change according to scroll pos", () => {
infinite = new Infinite({
useRecycle: false,
});
infinite.setItems([
{
key: 1,
startOutline: [0],
endOutline: [300],
},
{
key: 2,
startOutline: [300],
endOutline: [600],
},
{
key: 3,
startOutline: [600],
endOutline: [900],
},
]);
infinite.setSize(400);

// When
infinite.setCursors(0, 0);
const items1 = infinite.getRenderedVisibleItems();

infinite.setCursors(0, 1);
const items2 = infinite.getRenderedVisibleItems();

infinite.setCursors(1, 2);
const items3 = infinite.getRenderedVisibleItems();

const posItems1 = infinite.getRenderedVisibleItems(-200); // 1
const posItems2 = infinite.getRenderedVisibleItems(0); // 1 2
const posItems3 = infinite.getRenderedVisibleItems(250); // 1 2 3
const posItems4 = infinite.getRenderedVisibleItems(350); // 2 3
const posItems5 = infinite.getRenderedVisibleItems(700); // 3


// Then
expect(items1.map((item) => item.key)).to.be.deep.equals([1]);
expect(items2.map((item) => item.key)).to.be.deep.equals([1, 2]);
expect(items3.map((item) => item.key)).to.be.deep.equals([2, 3]);
expect(posItems1.map((item) => item.key)).to.be.deep.equals([1]);
expect(posItems2.map((item) => item.key)).to.be.deep.equals([1, 2]);
expect(posItems3.map((item) => item.key)).to.be.deep.equals([1, 2, 3]);
expect(posItems4.map((item) => item.key)).to.be.deep.equals([2, 3]);
expect(posItems5.map((item) => item.key)).to.be.deep.equals([3]);
});
it("should check if the cursor changes when you sync items", () => {
infinite = new Infinite({});
infinite.setItems([
Expand Down

0 comments on commit 92d7e93

Please sign in to comment.