|
10 | 10 | import Package from "./package.svelte"; |
11 | 11 | import NoInstalls from "./no-installs.svelte"; |
12 | 12 | import NoUpdates from "./no-updates.svelte"; |
13 | | - import { packagesStore } from "$libs/stores"; |
| 13 | + import { packagesStore, scrollStore } from "$libs/stores"; |
| 14 | + import { afterUpdate, beforeUpdate } from "svelte"; |
14 | 15 |
|
15 | 16 | const { packageList: allPackages } = packagesStore; |
16 | 17 | export let packageFilter: SideMenuOptions = SideMenuOptions.all; |
|
20 | 21 | let loadMore = 9; |
21 | 22 | let limit = loadMore + 9; |
22 | 23 |
|
| 24 | + const updateLimit = (value: number) => { |
| 25 | + limit += value; |
| 26 | + scrollStore.setLimit(packageFilter, limit); |
| 27 | + }; |
| 28 | +
|
23 | 29 | // TODO: figure out a better type strategy here so that this breaks if SideMenuOptions is updated |
24 | 30 | const pkgFilters: { [key: string]: (pkg: GUIPackage) => boolean } = { |
25 | 31 | [SideMenuOptions.all]: (_pkg: GUIPackage) => true, |
|
46 | 52 | const onScroll = (e: Event) => { |
47 | 53 | const target = e.target as HTMLInputElement; |
48 | 54 | scrollY = target.scrollTop || 0; |
| 55 | + scrollStore.setScrollPosition(packageFilter, scrollY); |
49 | 56 | }; |
50 | 57 |
|
51 | 58 | $: packages = $allPackages.filter(pkgFilters[packageFilter] || pkgFilters.all); |
|
56 | 63 | const minCardRows = Math.floor(node.scrollHeight / assumedCardHeight); |
57 | 64 | if (cardRows < minCardRows) { |
58 | 65 | const addLimit = 3 * (minCardRows - cardRows); |
59 | | - limit += addLimit; |
| 66 | + updateLimit(addLimit); |
60 | 67 | } |
61 | 68 | }; |
| 69 | +
|
| 70 | + let scrollElement: any = null; |
| 71 | + let prevFilter: SideMenuOptions | null; |
| 72 | +
|
| 73 | + // Restore the limit before the update... |
| 74 | + beforeUpdate(() => { |
| 75 | + if (prevFilter !== packageFilter) { |
| 76 | + limit = scrollStore.getLimit(packageFilter); |
| 77 | + } |
| 78 | + }); |
| 79 | +
|
| 80 | + // ...and scroll position after the update |
| 81 | + afterUpdate(() => { |
| 82 | + if (prevFilter !== packageFilter && scrollElement) { |
| 83 | + prevFilter = packageFilter; |
| 84 | + const scrollPosition = scrollStore.getScrollPosition(packageFilter); |
| 85 | + scrollElement.scrollTop = scrollPosition; |
| 86 | + } |
| 87 | + }); |
62 | 88 | </script> |
63 | 89 |
|
64 | 90 | <div class="relative h-full w-full"> |
65 | | - <ul class="flex flex-wrap content-start bg-black" use:watchResize={onResize} on:scroll={onScroll}> |
| 91 | + <ul |
| 92 | + bind:this={scrollElement} |
| 93 | + class="flex flex-wrap content-start bg-black" |
| 94 | + use:watchResize={onResize} |
| 95 | + on:scroll={onScroll} |
| 96 | + > |
66 | 97 | {#if packages.length > 0} |
67 | 98 | {#each packages as pkg, index} |
68 | 99 | {#if index < limit} |
|
84 | 115 | </section> |
85 | 116 | {/each} |
86 | 117 | {/if} |
87 | | - <InfiniteScroll threshold={100} on:loadMore={() => (limit += loadMore)} /> |
| 118 | + <InfiniteScroll threshold={100} on:loadMore={() => updateLimit(loadMore)} /> |
88 | 119 | </ul> |
89 | 120 | </div> |
90 | 121 |
|
|
0 commit comments