mirror of
https://github.com/jzillmann/pdf-to-markdown.git
synced 2025-06-25 12:01:45 +02:00
Don’t render all items at once
* Load the pages with together maximal 200 items * Load more once the page scroll nears the end
This commit is contained in:
parent
ad5fbfd15d
commit
3d48b88243
21
ui/src/actions/inView.ts
Normal file
21
ui/src/actions/inView.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
export default function inView(node: HTMLElement) {
|
||||||
|
const handleIntersect = (e: IntersectionObserverEntry[]) => {
|
||||||
|
node.dispatchEvent(
|
||||||
|
new CustomEvent('intersect', {
|
||||||
|
detail: e[0].isIntersecting,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const root = null;
|
||||||
|
const rootMargin = `0px 0px 300px 0px`;
|
||||||
|
const options = { root, rootMargin };
|
||||||
|
const observer = new IntersectionObserver(handleIntersect, options);
|
||||||
|
observer.observe(node);
|
||||||
|
|
||||||
|
return {
|
||||||
|
destroy() {
|
||||||
|
if (observer) observer.disconnect();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { scale } from 'svelte/transition';
|
import { scale, fade } from 'svelte/transition';
|
||||||
|
import inView from '../actions/inView';
|
||||||
import type AnnotatedColumn from '@core/debug/AnnotatedColumn';
|
import type AnnotatedColumn from '@core/debug/AnnotatedColumn';
|
||||||
import type Item from '@core/Item';
|
import type Item from '@core/Item';
|
||||||
import ColumnAnnotation from '../../../core/src/debug/ColumnAnnotation';
|
import ColumnAnnotation from '../../../core/src/debug/ColumnAnnotation';
|
||||||
@ -8,6 +9,19 @@
|
|||||||
export let itemsByPage: [number, Item[]][];
|
export let itemsByPage: [number, Item[]][];
|
||||||
export let maxPage: number;
|
export let maxPage: number;
|
||||||
export let pageIsPinned: boolean;
|
export let pageIsPinned: boolean;
|
||||||
|
let maxItemsToRenderInOneLoad = 200;
|
||||||
|
let renderedMaxPage = 0;
|
||||||
|
|
||||||
|
let renderedItemsByPage: [number, Item[]][];
|
||||||
|
$: {
|
||||||
|
if (pageIsPinned) {
|
||||||
|
renderedItemsByPage = itemsByPage;
|
||||||
|
renderedMaxPage = 0;
|
||||||
|
} else {
|
||||||
|
calculateNextPageToRenderTo();
|
||||||
|
renderedItemsByPage = itemsByPage.slice(0, renderedMaxPage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function format(value: object) {
|
function format(value: object) {
|
||||||
if (typeof value === 'number') {
|
if (typeof value === 'number') {
|
||||||
@ -25,8 +39,21 @@
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO if no ADDED/REMOVE cols
|
function calculateNextPageToRenderTo() {
|
||||||
// - have highlight declarations in descriptor
|
if (renderedMaxPage >= maxPage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let itemCount = 0;
|
||||||
|
for (let index = 0; index < itemsByPage.length; index++) {
|
||||||
|
renderedMaxPage++;
|
||||||
|
const [_, items] = itemsByPage[index];
|
||||||
|
itemCount += items.length;
|
||||||
|
if (itemCount > maxItemsToRenderInOneLoad) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// console.log(`Render pages 0 to ${renderedMaxPage} with ${itemCount} items`);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Item table -->
|
<!-- Item table -->
|
||||||
@ -44,13 +71,13 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{#each itemsByPage as [pageNumber, items], pageIdx}
|
{#each renderedItemsByPage as [pageNumber, items], pageIdx}
|
||||||
<!-- Separator between pages -->
|
<!-- Separator between pages -->
|
||||||
{#if pageIdx > 0}
|
{#if pageIdx > 0}
|
||||||
<tr class="h-5" />
|
<tr class="h-5" />
|
||||||
{/if}
|
{/if}
|
||||||
{#each items as item, itemIdx}
|
{#each items as item, itemIdx}
|
||||||
<tr>
|
<tr in:fade>
|
||||||
<!-- Page number in first page item row -->
|
<!-- Page number in first page item row -->
|
||||||
{#if itemIdx === 0}
|
{#if itemIdx === 0}
|
||||||
<td class="page bg-gray-50">
|
<td class="page bg-gray-50">
|
||||||
@ -69,6 +96,15 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
{#if !pageIsPinned}
|
||||||
|
{#if renderedMaxPage < itemsByPage.length}
|
||||||
|
<span use:inView on:intersect={({ detail }) => detail && calculateNextPageToRenderTo()} />
|
||||||
|
<div class="my-6 text-center text-2xl">...</div>
|
||||||
|
{:else}
|
||||||
|
<div class="my-6 text-center text-2xl">FIN!</div>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.page {
|
.page {
|
||||||
@apply text-lg;
|
@apply text-lg;
|
||||||
|
7
ui/types/static.d.ts
vendored
7
ui/types/static.d.ts
vendored
@ -3,6 +3,13 @@
|
|||||||
|
|
||||||
declare module 'svelte-file-dropzone';
|
declare module 'svelte-file-dropzone';
|
||||||
|
|
||||||
|
declare namespace svelte.JSX {
|
||||||
|
interface HTMLProps<T> {
|
||||||
|
// inView.ts action
|
||||||
|
onintersect?: (e: CustomEvent) => void;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* CSS MODULES */
|
/* CSS MODULES */
|
||||||
declare module '*.module.css' {
|
declare module '*.module.css' {
|
||||||
const classes: { [key: string]: string };
|
const classes: { [key: string]: string };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user