diff --git a/public/index.css b/public/index.css
index f34d144d8..56b4b9f14 100644
--- a/public/index.css
+++ b/public/index.css
@@ -22,6 +22,27 @@ body {
background-color: var(--color-background-default);
}
+a,
+a:link,
+a:visited,
+a:hover,
+a:active,
+a:focus {
+ color: inherit;
+ text-decoration: none;
+ background: transparent;
+ cursor: pointer;
+}
+
+a {
+ display: inline;
+ font-weight: inherit;
+ font-style: inherit;
+ font-size: inherit;
+ line-height: inherit;
+ font-family: inherit;
+}
+
::selection {
background: var(--color-fill-yellow);
color: var(--color-foreground-black);
diff --git a/src/components/HomeSidebar.svelte b/src/components/HomeSidebar.svelte
index a4bdd2275..f20f8b11d 100644
--- a/src/components/HomeSidebar.svelte
+++ b/src/components/HomeSidebar.svelte
@@ -27,7 +27,6 @@
align-items: center;
gap: 0.5rem;
background-color: var(--color-background-float);
- clip-path: var(--1px-corner-fill);
display: flex;
font-size: var(--font-size-small);
justify-content: space-between;
@@ -54,65 +53,58 @@
styleFlexDirection="column"
styleGap="2px"
styleBackgroundColor="var(--color-background-float)">
-
-
-
router.push({ resource: "home", activeTab: "all" })}>
+ href={router.routeToPath({
+ resource: "home",
+ activeTab: "all",
+ })}>
Repositories
{repoCount.total}
-
-
-
-
-
-
-
-
-
-
+
diff --git a/src/lib/router.ts b/src/lib/router.ts
index 8b350f328..c5c9bf2df 100644
--- a/src/lib/router.ts
+++ b/src/lib/router.ts
@@ -1,4 +1,9 @@
+import {
+ homeRouteToPath as homeRouteToPath,
+ homeUrlToRoute,
+} from "@app/views/home/router";
import { repoRouteToPath, repoUrlToRoute } from "@app/views/repo/router";
+import { on } from "svelte/events";
import { get, writable } from "svelte/store";
import * as mutexExecutor from "@app/lib/mutexExecutor";
@@ -50,7 +55,27 @@ async function navigateToUrl(
}
}
-window.addEventListener("popstate", () => loadFromLocation());
+const offPopstate = on(window, "popstate", () => loadFromLocation());
+
+const offNavigateAnchor = on(document, "click", e => {
+ const [anchor] = e
+ .composedPath()
+ .flatMap(target => (target instanceof HTMLAnchorElement ? [target] : []));
+ if (anchor && anchor.getAttribute("href")?.startsWith("/")) {
+ e.preventDefault();
+ void navigateToUrl(
+ "push",
+ new URL(anchor.getAttribute("href") ?? "", window.location.href),
+ );
+ }
+});
+
+if (import.meta.hot) {
+ import.meta.hot.dispose(() => {
+ offPopstate();
+ offNavigateAnchor();
+ });
+}
const loadExecutor = mutexExecutor.create();
@@ -100,13 +125,12 @@ function urlToRoute(url: URL): Route | null {
const segments = url.pathname.substring(1).split("/");
const resource = segments.shift();
+ const homeRoute = homeUrlToRoute(url);
+ if (homeRoute) {
+ return homeRoute;
+ }
+
switch (resource) {
- case "": {
- return {
- resource: "home",
- activeTab: "all",
- };
- }
case "repos": {
return repoUrlToRoute(segments, url.searchParams);
}
@@ -118,7 +142,7 @@ function urlToRoute(url: URL): Route | null {
export function routeToPath(route: Route): string {
if (route.resource === "home") {
- return "/";
+ return homeRouteToPath(route);
} else if (
route.resource === "repo.home" ||
route.resource === "repo.createIssue" ||
diff --git a/src/views/home/router.ts b/src/views/home/router.ts
index aaf426fd6..43bb1a137 100644
--- a/src/views/home/router.ts
+++ b/src/views/home/router.ts
@@ -2,10 +2,19 @@ import type { Config } from "@bindings/config/Config";
import type { RepoCount } from "@bindings/repo/RepoCount";
import type { RepoInfo } from "@bindings/repo/RepoInfo";
+import z from "zod";
+
import { invoke } from "@app/lib/invoke";
export type HomeReposTab = "all" | "delegate" | "private" | "contributor";
+const homeReposTabSchema = z.union([
+ z.literal("all"),
+ z.literal("delegate"),
+ z.literal("private"),
+ z.literal("contributor"),
+]);
+
export interface HomeRoute {
resource: "home";
activeTab: HomeReposTab;
@@ -56,3 +65,22 @@ export async function loadHome(route: HomeRoute): Promise {
},
};
}
+
+export function homeUrlToRoute(url: URL): HomeRoute | undefined {
+ if (url.pathname === "/") {
+ return {
+ resource: "home",
+ activeTab: homeReposTabSchema
+ .catch(() => "all" as const)
+ .parse(url.searchParams.get("tab")),
+ };
+ }
+}
+
+export function homeRouteToPath(route: HomeRoute): string {
+ const searchParams = new URLSearchParams();
+ if (route.activeTab !== "all") {
+ searchParams.append("tab", route.activeTab);
+ }
+ return `/?${searchParams.toString()}`;
+}