Skip to content

Commit 645e111

Browse files
feat: make the releases count actually accurate since the latest visit
1 parent 8a8dff5 commit 645e111

File tree

2 files changed

+53
-13
lines changed

2 files changed

+53
-13
lines changed

src/routes/package/SidePanel.svelte

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script lang="ts">
22
import type { ClassValue } from "svelte/elements";
3+
import { browser } from "$app/environment";
34
import { page } from "$app/state";
45
import { ChevronRight } from "@lucide/svelte";
56
import type { GitHubRelease } from "$lib/server/github-cache";
@@ -13,6 +14,8 @@
1314
import { Separator } from "$lib/components/ui/separator";
1415
import * as Card from "$lib/components/ui/card";
1516
17+
type CleanRelease = { cleanName: string; cleanVersion: string } & GitHubRelease;
18+
1619
type Props = {
1720
packageName?: string;
1821
allPackages?: Prettify<
@@ -33,7 +36,7 @@
3336
"dataFilter" | "metadataFromTag" | "changelogContentsReplacer"
3437
>
3538
>;
36-
releases: ({ cleanName: string; cleanVersion: string } & GitHubRelease)[] | undefined;
39+
releases: CleanRelease[] | undefined;
3740
}
3841
| undefined
3942
>;
@@ -58,6 +61,41 @@
5861
storedPrereleaseState.value = showPrereleases;
5962
});
6063
});
64+
65+
/**
66+
* Extract the data from the {@link Props.otherReleases|otherReleases}
67+
* props.
68+
*
69+
* @param pkgName the package name to extract releases fo
70+
* @returns the {@link Promise} of releases, or `undefined`
71+
*/
72+
function getBadgeDataFromOther(pkgName: string) {
73+
const data = Object.entries(otherReleases).find(
74+
([k]) => k.localeCompare(pkgName, undefined, { sensitivity: "base" }) === 0
75+
);
76+
if (!data) return undefined;
77+
const [, v] = data;
78+
return v;
79+
}
80+
81+
/**
82+
* Filter the releases to exclude those that have already been seen
83+
*
84+
* @param pkgName the package name for the releases
85+
* @param releases the releases to filter
86+
* @returns the filtered releases
87+
*/
88+
function getUnvisitedReleases(pkgName: string, releases: CleanRelease[] | undefined) {
89+
if (!releases || !browser) return [];
90+
91+
const lastVisitedItem = localStorage.getItem(`last-visited-${pkgName}`);
92+
if (!lastVisitedItem) return [];
93+
const lastVisitedDate = new Date(lastVisitedItem);
94+
95+
return releases.filter(
96+
({ created_at, published_at }) => new Date(published_at ?? created_at) > lastVisitedDate
97+
);
98+
}
6199
</script>
62100

63101
{#snippet newBadge(count: number)}
@@ -98,9 +136,7 @@
98136
<ul class="space-y-2">
99137
<!-- Sub-items -->
100138
{#each packages as { pkg } (pkg.name)}
101-
{@const linkedBadgeData = Object.entries(otherReleases).find(
102-
([k]) => k.localeCompare(pkg.name, undefined, { sensitivity: "base" }) === 0
103-
)}
139+
{@const linkedBadgeData = getBadgeDataFromOther(pkg.name)}
104140
<li>
105141
{#if page.url.pathname.endsWith(`/${pkg.name}`)}
106142
<!-- Active sub-item -->
@@ -114,9 +150,10 @@
114150
<span class="underline-offset-4 group-hover:underline">{pkg.name}</span>
115151
<span class="ml-auto flex items-center gap-1">
116152
{#if linkedBadgeData}
117-
{@const [, p] = linkedBadgeData}
118-
{#await p then d}
119-
{@render newBadge(d?.releases?.length ?? 0)}
153+
{#await linkedBadgeData then data}
154+
{@render newBadge(
155+
getUnvisitedReleases(pkg.name, data?.releases).length
156+
)}
120157
{/await}
121158
{/if}
122159
<ChevronRight
@@ -131,9 +168,7 @@
131168
{:else}
132169
<!-- Categories with 1 sub-item -->
133170
{@const firstPackageName = packages[0]?.pkg.name ?? ""}
134-
{@const linkedBadgeData = Object.entries(otherReleases).find(
135-
([k]) => k.localeCompare(firstPackageName, undefined, { sensitivity: "base" }) === 0
136-
)}
171+
{@const linkedBadgeData = getBadgeDataFromOther(firstPackageName)}
137172
{#if page.url.pathname.endsWith(`/${firstPackageName}`)}
138173
<!-- Active category -->
139174
<h3 class="text-xl font-bold text-primary underline underline-offset-4">
@@ -148,9 +183,10 @@
148183
<span class="underline-offset-4 group-hover:underline">{category.name}</span>
149184
<span class="ml-auto flex items-center gap-1">
150185
{#if linkedBadgeData}
151-
{@const [, p] = linkedBadgeData}
152-
{#await p then d}
153-
{@render newBadge(d?.releases?.length ?? 0)}
186+
{#await linkedBadgeData then data}
187+
{@render newBadge(
188+
getUnvisitedReleases(firstPackageName, data?.releases).length
189+
)}
154190
{/await}
155191
{/if}
156192
<ChevronRight

src/routes/package/[...package]/+page.svelte

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
.sort((a, b) => semver.compare(a.cleanVersion, b.cleanVersion))[0]
2222
);
2323
let showPrereleases = $state(true);
24+
25+
$effect(() => {
26+
localStorage.setItem(`last-visited-${data.currentPackage.pkg.name}`, new Date().toISOString());
27+
});
2428
</script>
2529

2630
{#snippet loading()}

0 commit comments

Comments
 (0)