@internetarchive/collection-browser 4.3.2-alpha-webdev7939.0 → 4.3.2-alpha-webdev7939.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/app-root.js +676 -672
- package/dist/src/app-root.js.map +1 -1
- package/dist/src/collection-browser.d.ts +23 -0
- package/dist/src/collection-browser.js +74 -6
- package/dist/src/collection-browser.js.map +1 -1
- package/package.json +2 -2
- package/src/app-root.ts +1254 -1251
- package/src/collection-browser.ts +97 -5
|
@@ -421,7 +421,7 @@ export class CollectionBrowser
|
|
|
421
421
|
const model = this.dataSource.getTileModelAt(index);
|
|
422
422
|
/**
|
|
423
423
|
* If we encounter a model we don't have yet and we're not in the middle of an
|
|
424
|
-
* automated scroll, fetch the page and
|
|
424
|
+
* automated scroll, schedule a fetch for the missing page and return undefined.
|
|
425
425
|
* The datasource will be updated once the page is loaded and the cell will be rendered.
|
|
426
426
|
*
|
|
427
427
|
* We disable it during the automated scroll since we don't want to fetch pages for intervening cells the
|
|
@@ -429,11 +429,61 @@ export class CollectionBrowser
|
|
|
429
429
|
*/
|
|
430
430
|
if (!model && !this.isScrollingToCell && this.dataSource.queryInitialized) {
|
|
431
431
|
const pageNumber = Math.floor(index / this.pageSize) + 1;
|
|
432
|
-
this.
|
|
432
|
+
this.scheduleDeferredPageFetch(pageNumber);
|
|
433
433
|
}
|
|
434
434
|
return model;
|
|
435
435
|
}
|
|
436
436
|
|
|
437
|
+
/**
|
|
438
|
+
* Debounce delay for page fetches initiated by new cells becoming visible.
|
|
439
|
+
* Tuned so quick scrolling through unloaded regions doesn't send rapid-fire
|
|
440
|
+
* search requests for every page we pass through, but to still feel responsive
|
|
441
|
+
* when the scroll ends.
|
|
442
|
+
*/
|
|
443
|
+
private static readonly DEFERRED_FETCH_DELAY_MS = 150;
|
|
444
|
+
|
|
445
|
+
private deferredFetchTimer = 0;
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Schedules a fetch for the given page, debounced to ensure we don't
|
|
449
|
+
* rapid-fire fetches while scrolling through pages quickly.
|
|
450
|
+
*
|
|
451
|
+
* If there's no pending fetch timer yet, it will fire a fetch immediately.
|
|
452
|
+
* Otherwise, it will reset any existing timer. In either case, a deferred
|
|
453
|
+
* fetch for the visible pages is scheduled after a brief delay to account
|
|
454
|
+
* for whatever pages we land on after scrolling.
|
|
455
|
+
*/
|
|
456
|
+
private scheduleDeferredPageFetch(pageNumber: number): void {
|
|
457
|
+
if (!this.deferredFetchTimer) {
|
|
458
|
+
this.dataSource.fetchPage(pageNumber);
|
|
459
|
+
} else {
|
|
460
|
+
window.clearTimeout(this.deferredFetchTimer);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
this.deferredFetchTimer = window.setTimeout(() => {
|
|
464
|
+
this.deferredFetchTimer = 0;
|
|
465
|
+
this.fetchVisiblePages();
|
|
466
|
+
}, CollectionBrowser.DEFERRED_FETCH_DELAY_MS);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Fetch each currently-visible page whose first cell still has no
|
|
471
|
+
* loaded model.
|
|
472
|
+
*/
|
|
473
|
+
private fetchVisiblePages(): void {
|
|
474
|
+
const visibleIndices = this.infiniteScroller?.getVisibleCellIndices() ?? [];
|
|
475
|
+
const visiblePages = new Set(
|
|
476
|
+
visibleIndices.map(i => Math.floor(i / this.pageSize) + 1),
|
|
477
|
+
);
|
|
478
|
+
|
|
479
|
+
for (const page of visiblePages) {
|
|
480
|
+
const firstCellOfPage = (page - 1) * this.pageSize;
|
|
481
|
+
if (!this.dataSource.getTileModelAt(firstCellOfPage)) {
|
|
482
|
+
this.dataSource.fetchPage(page);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
437
487
|
// this is the total number of tiles we expect if
|
|
438
488
|
// the data returned is a full page worth
|
|
439
489
|
// this is useful for putting in placeholders for the expected number of tiles
|
|
@@ -1891,6 +1941,11 @@ export class CollectionBrowser
|
|
|
1891
1941
|
window.removeEventListener('popstate', this.boundNavigationHandler);
|
|
1892
1942
|
}
|
|
1893
1943
|
|
|
1944
|
+
if (this.deferredFetchTimer) {
|
|
1945
|
+
window.clearTimeout(this.deferredFetchTimer);
|
|
1946
|
+
this.deferredFetchTimer = 0;
|
|
1947
|
+
}
|
|
1948
|
+
|
|
1894
1949
|
this.leftColIntersectionObserver?.disconnect();
|
|
1895
1950
|
this.facetsIntersectionObserver?.disconnect();
|
|
1896
1951
|
window.removeEventListener('resize', this.updateLeftColumnHeight);
|
|
@@ -2143,7 +2198,13 @@ export class CollectionBrowser
|
|
|
2143
2198
|
private visibleCellsChanged(
|
|
2144
2199
|
e: CustomEvent<{ visibleCellIndices: number[] }>,
|
|
2145
2200
|
) {
|
|
2146
|
-
if (this.isScrollingToCell)
|
|
2201
|
+
if (this.isScrollingToCell) {
|
|
2202
|
+
// eslint-disable-next-line no-console
|
|
2203
|
+
console.log(
|
|
2204
|
+
`[CB visibleCellsChanged] BAIL isScrollingToCell=true visible=[${e.detail.visibleCellIndices.join(',')}]`,
|
|
2205
|
+
);
|
|
2206
|
+
return;
|
|
2207
|
+
}
|
|
2147
2208
|
const { visibleCellIndices } = e.detail;
|
|
2148
2209
|
if (visibleCellIndices.length === 0) return;
|
|
2149
2210
|
|
|
@@ -2155,6 +2216,20 @@ export class CollectionBrowser
|
|
|
2155
2216
|
const lastVisibleCellIndex = visibleCellIndices[lastIndexWithinCurrentPage];
|
|
2156
2217
|
const lastVisibleCellPage =
|
|
2157
2218
|
Math.floor(lastVisibleCellIndex / this.pageSize) + 1;
|
|
2219
|
+
|
|
2220
|
+
// Detect out-of-order Set: compare the indices we got to a sorted copy.
|
|
2221
|
+
const sorted = [...visibleCellIndices].sort((a, b) => a - b);
|
|
2222
|
+
const isSorted = sorted.every((v, i) => v === visibleCellIndices[i]);
|
|
2223
|
+
const minIdx = sorted[0];
|
|
2224
|
+
const maxIdx = sorted[sorted.length - 1];
|
|
2225
|
+
const first10 = visibleCellIndices.slice(0, 10).join(',');
|
|
2226
|
+
const last10 = visibleCellIndices.slice(-10).join(',');
|
|
2227
|
+
|
|
2228
|
+
// eslint-disable-next-line no-console
|
|
2229
|
+
console.log(
|
|
2230
|
+
`[CB visibleCellsChanged] computedPage=${lastVisibleCellPage} lastIdx=${lastVisibleCellIndex} sampledAt=${lastIndexWithinCurrentPage} len=${visibleCellIndices.length} sorted=${isSorted} min=${minIdx} max=${maxIdx} scrollY=${window.scrollY} first10=[${first10}] last10=[${last10}]`,
|
|
2231
|
+
);
|
|
2232
|
+
|
|
2158
2233
|
if (this.currentPage !== lastVisibleCellPage) {
|
|
2159
2234
|
this.currentPage = lastVisibleCellPage;
|
|
2160
2235
|
}
|
|
@@ -2345,6 +2420,10 @@ export class CollectionBrowser
|
|
|
2345
2420
|
|
|
2346
2421
|
private async scrollToPage(pageNumber: number): Promise<void> {
|
|
2347
2422
|
const cellIndexToScrollTo = this.pageSize * (pageNumber - 1);
|
|
2423
|
+
// eslint-disable-next-line no-console
|
|
2424
|
+
console.log(
|
|
2425
|
+
`[CB scrollToPage] ENTRY page=${pageNumber} targetCell=${cellIndexToScrollTo} pagesToRender=${this.pagesToRender} estimatedTileCount=${this.estimatedTileCount} itemCount=${this.infiniteScroller?.itemCount} scrollY=${window.scrollY}`,
|
|
2426
|
+
);
|
|
2348
2427
|
|
|
2349
2428
|
// Wait for the infinite scroller be rendered before proceeding
|
|
2350
2429
|
let waitAttempts = 0;
|
|
@@ -2352,7 +2431,13 @@ export class CollectionBrowser
|
|
|
2352
2431
|
await this.updateComplete;
|
|
2353
2432
|
waitAttempts++;
|
|
2354
2433
|
}
|
|
2355
|
-
if (!this.infiniteScroller)
|
|
2434
|
+
if (!this.infiniteScroller) {
|
|
2435
|
+
// eslint-disable-next-line no-console
|
|
2436
|
+
console.log(
|
|
2437
|
+
`[CB scrollToPage] NO_SCROLLER after wait waitAttempts=${waitAttempts}`,
|
|
2438
|
+
);
|
|
2439
|
+
return;
|
|
2440
|
+
}
|
|
2356
2441
|
|
|
2357
2442
|
// The scroller have its default `itemCount=0`, so propagate our estimated
|
|
2358
2443
|
// tile count before jumping to the desired page.
|
|
@@ -2368,8 +2453,15 @@ export class CollectionBrowser
|
|
|
2368
2453
|
});
|
|
2369
2454
|
|
|
2370
2455
|
this.isScrollingToCell = true;
|
|
2371
|
-
await this.infiniteScroller.scrollToCell(
|
|
2456
|
+
const scrolled = await this.infiniteScroller.scrollToCell(
|
|
2457
|
+
cellIndexToScrollTo,
|
|
2458
|
+
true,
|
|
2459
|
+
);
|
|
2372
2460
|
this.isScrollingToCell = false;
|
|
2461
|
+
// eslint-disable-next-line no-console
|
|
2462
|
+
console.log(
|
|
2463
|
+
`[CB scrollToPage] DONE page=${pageNumber} targetCell=${cellIndexToScrollTo} scrolled=${scrolled} scrollY=${window.scrollY}`,
|
|
2464
|
+
);
|
|
2373
2465
|
this.infiniteScroller.refreshAllVisibleCells();
|
|
2374
2466
|
}
|
|
2375
2467
|
|