-
Notifications
You must be signed in to change notification settings - Fork 4
feat!: badges in sidebar #56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
1fb8307
feat: feature scaffolding
WarningImHack3r ffc643a
fix(lint): remove useless (for now) variable
WarningImHack3r 3cccb7d
refactor: fix the need to rerun at page change (still need to fix laz…
WarningImHack3r bc1fd17
fix: improve the syntax
WarningImHack3r ef11f3d
Merge branch 'main' into sidebar-v2
WarningImHack3r a9cd06b
Merge branch 'main' into sidebar-v2
WarningImHack3r 961d1f5
style: finalize badge style
WarningImHack3r 0d7aeb5
style: fix hover state
WarningImHack3r 3b5935f
refactor: move the sidebar into the layout
WarningImHack3r 35a4f0c
revert: temporarily disable prereleases toggle
WarningImHack3r 70ea64b
Merge branch 'main' into sidebar-v2
WarningImHack3r 0b6b01c
fix: port 0e491b4 to sidebar v2
WarningImHack3r 8a8dff5
style: fix responsive layout for sidebar button
WarningImHack3r 645e111
feat: make the releases count actually accurate since the latest visit
WarningImHack3r 8238db7
feat: set releases newer than a week if package never visited
WarningImHack3r 318331a
fix: apply rabbit suggestions
WarningImHack3r File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| import semver from "semver"; | ||
| import { gitHubCache, type GitHubRelease } from "$lib/server/github-cache"; | ||
| import { discoverer } from "$lib/server/package-discoverer"; | ||
| import type { Repository } from "$lib/repositories"; | ||
| import type { Prettify } from "$lib/types"; | ||
|
|
||
| /** | ||
| * Get all the releases for a single package. | ||
| * | ||
| * @param packageName the package to get the releases for | ||
| * @param allPackages all the known packages | ||
| * @returns the package's repository alongside its releases, or | ||
| * undefined if not found | ||
| */ | ||
| async function getPackageReleases( | ||
| packageName: string, | ||
| allPackages: Awaited<ReturnType<typeof discoverer.getOrDiscoverCategorized>> | ||
| ) { | ||
| let currentPackage: | ||
| | Prettify< | ||
| Omit<Repository, "dataFilter" | "metadataFromTag" | "changelogContentsReplacer"> & | ||
| Pick<(typeof allPackages)[number]["packages"][number], "pkg"> | ||
| > | ||
| | undefined = undefined; | ||
| const foundVersions = new Set<string>(); | ||
| const releases: ({ cleanName: string; cleanVersion: string } & GitHubRelease)[] = []; | ||
|
|
||
| // Discover releases | ||
| console.log("Starting loading releases..."); | ||
| for (const { category, packages } of allPackages) { | ||
| for (const { pkg, ...repo } of packages) { | ||
| if (pkg.name.localeCompare(packageName, undefined, { sensitivity: "base" }) !== 0) continue; | ||
|
|
||
| // 1. Get releases | ||
| const cachedReleases = await gitHubCache.getReleases({ ...repo, category }); | ||
| console.log( | ||
| `${cachedReleases.length} releases found for repo ${repo.owner}/${repo.repoName}` | ||
| ); | ||
|
|
||
| // 2. Filter out invalid ones | ||
| const validReleases = cachedReleases | ||
| .filter(release => { | ||
| const [name] = repo.metadataFromTag(release.tag_name); | ||
| return ( | ||
| (repo.dataFilter?.(release) ?? true) && | ||
| pkg.name.localeCompare(name, undefined, { sensitivity: "base" }) === 0 | ||
| ); | ||
| }) | ||
| .sort((a, b) => { | ||
| const [, firstVersion] = repo.metadataFromTag(a.tag_name); | ||
| const [, secondVersion] = repo.metadataFromTag(b.tag_name); | ||
| return semver.rcompare(firstVersion, secondVersion); | ||
| }); | ||
| console.log("Length after filtering:", validReleases.length); | ||
| // Get the releases matching the slug, or all of them if none | ||
| // (the latter case for repos with no package in names) | ||
| console.log("Final filtered count:", validReleases.length); | ||
|
|
||
| // 3. For each release, check if it is already found, searching by versions | ||
| const { dataFilter, metadataFromTag, changelogContentsReplacer, ...rest } = repo; | ||
| for (const release of validReleases) { | ||
| const [cleanName, cleanVersion] = repo.metadataFromTag(release.tag_name); | ||
| console.log(`Release ${release.tag_name}, extracted version: ${cleanVersion}`); | ||
| if (foundVersions.has(cleanVersion)) continue; | ||
|
|
||
| // If not, add its version to the set and itself to the final version | ||
| const currentNewestVersion = [...foundVersions].sort(semver.rcompare)[0]; | ||
| console.log("Current newest version", currentNewestVersion); | ||
| foundVersions.add(cleanVersion); | ||
| releases.push({ cleanName, cleanVersion, ...release }); | ||
|
|
||
| // If it is newer than the newest we got, set this repo as the "final repo" | ||
| if (!currentNewestVersion || semver.gt(cleanVersion, currentNewestVersion)) { | ||
| console.log( | ||
| `Current newest version "${currentNewestVersion}" doesn't exist or is lesser than ${cleanVersion}, setting ${rest.owner}/${rest.repoName} as final repo` | ||
| ); | ||
| currentPackage = { | ||
| category, | ||
| pkg, | ||
| ...rest | ||
| }; | ||
| } | ||
| } | ||
| console.log("Done"); | ||
| } | ||
| } | ||
|
|
||
| return currentPackage | ||
| ? { | ||
| releasesRepo: currentPackage, | ||
| releases: releases.toSorted( | ||
| (a, b) => | ||
| new Date(b.published_at ?? b.created_at).getTime() - | ||
| new Date(a.published_at ?? a.created_at).getTime() | ||
| ) | ||
| } | ||
| : undefined; | ||
| } | ||
|
|
||
| /** | ||
| * Get all the repositories and releases for all the | ||
| * known packages. | ||
| * | ||
| * @param allPackages all the known packages | ||
| * @returns a map of package names to their awaitable result | ||
| */ | ||
| function getAllPackagesReleases( | ||
| allPackages: Awaited<ReturnType<typeof discoverer.getOrDiscoverCategorized>> | ||
| ) { | ||
| const packages = allPackages.flatMap(({ packages }) => packages); | ||
|
|
||
| return packages.reduce<Record<string, ReturnType<typeof getPackageReleases>>>( | ||
| (acc, { pkg: { name } }) => { | ||
| if (acc[name]) | ||
| console.warn( | ||
| `Duplicate package "${name}" while aggregating packages releases; this should not happen!` | ||
| ); | ||
| acc[name] = getPackageReleases(name, allPackages); | ||
| return acc; | ||
| }, | ||
| {} | ||
| ); | ||
| } | ||
|
|
||
| /** | ||
| * The goal of this load function is to serve any `[...package]` | ||
| * page by handing it a bunch of promises, so it can await the one | ||
| * it needs. The other ones are for the sidebar badges, so the page | ||
| * doesn't have to re-run the data loading every time we switch from | ||
| * a package to another. | ||
| */ | ||
| export async function load() { | ||
| // 1. Get all the packages | ||
| const categorizedPackages = await discoverer.getOrDiscoverCategorized(); | ||
|
|
||
| // 2. Use them to get a map of packages to promises of releases | ||
| const allReleases = getAllPackagesReleases(categorizedPackages); | ||
|
|
||
| // 3. Send all that down to the page's load function | ||
| return { allReleases }; | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| <script lang="ts"> | ||
| import { page } from "$app/state"; | ||
| import { Menu } from "@lucide/svelte"; | ||
| import { Button } from "$lib/components/ui/button"; | ||
| import * as Sheet from "$lib/components/ui/sheet"; | ||
| import SidePanel from "./SidePanel.svelte"; | ||
| let { data, children } = $props(); | ||
| let showPrereleases = $state(true); | ||
| </script> | ||
|
|
||
| <div class="relative mt-8 flex gap-8 lg:mt-0"> | ||
| <div class="flex-1"> | ||
| {@render children()} | ||
| </div> | ||
|
|
||
| <Sheet.Root> | ||
| <Sheet.Trigger> | ||
| {#snippet child({ props })} | ||
| <Button | ||
| {...props} | ||
| variant="secondary" | ||
| class={[ | ||
| "absolute right-0 mt-12 ml-auto lg:hidden", | ||
| page.data.currentPackage.pkg.description?.length && "mt-16" | ||
| ]} | ||
| > | ||
| <Menu /> | ||
| <span class="sr-only">Menu</span> | ||
| </Button> | ||
| {/snippet} | ||
| </Sheet.Trigger> | ||
| <Sheet.Content class="overflow-y-auto"> | ||
| <Sheet.Header> | ||
| <Sheet.Title>Packages</Sheet.Title> | ||
| </Sheet.Header> | ||
| <SidePanel | ||
| headless | ||
| packageName={page.data.currentPackage.pkg.name} | ||
| allPackages={data.displayablePackages} | ||
| otherReleases={data.allReleases} | ||
| bind:showPrereleases | ||
| class="my-8" | ||
| /> | ||
| </Sheet.Content> | ||
| </Sheet.Root> | ||
|
|
||
| <SidePanel | ||
| packageName={page.data.currentPackage.pkg.name} | ||
| allPackages={data.displayablePackages} | ||
| otherReleases={data.allReleases} | ||
| class={[ | ||
| "mt-35 hidden h-fit w-100 shrink-0 lg:flex", | ||
| page.data.currentPackage.pkg.description?.length && "mt-45" | ||
| ]} | ||
| bind:showPrereleases | ||
| /> | ||
| </div> |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.