diff --git a/src/App.svelte b/src/App.svelte index 3ade0efa5..53d011b33 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -13,6 +13,7 @@ import Home from "@app/views/Home.svelte"; import Issue from "@app/views/repo/Issue.svelte"; import Issues from "@app/views/repo/Issues.svelte"; + import Patch from "@app/views/repo/Patch.svelte"; import Patches from "@app/views/repo/Patches.svelte"; const activeRouteStore = router.activeRouteStore; @@ -56,6 +57,8 @@ {:else if $activeRouteStore.resource === "repo.issues"} +{:else if $activeRouteStore.resource === "repo.patch"} + {:else if $activeRouteStore.resource === "repo.patches"} {:else if $activeRouteStore.resource === "authenticationError"} diff --git a/src/components/PatchTeaser.svelte b/src/components/PatchTeaser.svelte index acd6c24f3..7ecdc743b 100644 --- a/src/components/PatchTeaser.svelte +++ b/src/components/PatchTeaser.svelte @@ -2,8 +2,14 @@ import type { Patch } from "@bindings/Patch"; import type { Stats } from "@bindings/Stats"; - import { formatOid, formatTimestamp } from "@app/lib/utils"; + import { + formatOid, + formatTimestamp, + patchStatusBackgroundColor, + patchStatusColor, + } from "@app/lib/utils"; import { invoke } from "@tauri-apps/api/core"; + import { push } from "@app/lib/router"; import DiffStatBadge from "./DiffStatBadge.svelte"; import Icon from "./Icon.svelte"; @@ -12,20 +18,6 @@ export let patch: Patch; export let rid: string; - - const statusColor: Record = { - draft: "var(--color-fill-gray)", - open: "var(--color-fill-success)", - archived: "var(--color-foreground-yellow)", - merged: "var(--color-fill-primary)", - }; - - const statusBackgroundColor: Record = { - draft: "var(--color-fill-ghost)", - open: "var(--color-fill-diff-green)", - archived: "var(--color-fill-private)", - merged: "var(--color-fill-delegate)", - }; -
+ +
{ + void push({ resource: "repo.patch", rid, patch: patch.id }); + }}>
+ style:color={patchStatusColor[patch.state.status]} + style:background-color={patchStatusBackgroundColor[patch.state.status]}>
= { + draft: "var(--color-fill-gray)", + open: "var(--color-fill-success)", + archived: "var(--color-foreground-yellow)", + merged: "var(--color-fill-primary)", +}; + +export const patchStatusBackgroundColor: Record< + Patch["state"]["status"], + string +> = { + draft: "var(--color-fill-ghost)", + open: "var(--color-fill-diff-green)", + archived: "var(--color-fill-private)", + merged: "var(--color-fill-delegate)", +}; diff --git a/src/views/repo/Patch.svelte b/src/views/repo/Patch.svelte new file mode 100644 index 000000000..f193f37e7 --- /dev/null +++ b/src/views/repo/Patch.svelte @@ -0,0 +1,152 @@ + + + + + + + + + + +
+ + {project.data.name} +
+ + + Patches +
+ + + + + + + +
+ +
+ Patches +
+
+ {project.meta.patches.draft + + project.meta.patches.open + + project.meta.patches.merged + + project.meta.patches.archived} +
+
+
+ +
+ {#each patches as sidebarPatch} + +
+
+ +
+ + + +
+ + {/each} +
+
+ +
+
+ +
+
+ {#if revisions[0].description.slice(-1)[0].body !== ""} + + {:else} + No description. + {/if} +
+ + opened +
{formatOid(patch.id)}
+ {formatTimestamp(patch.timestamp)} +
+
+
Revisions
+ {#each revisions as revision} +
{formatOid(revision.oid)}
+ {/each} +
+
diff --git a/src/views/repo/router.ts b/src/views/repo/router.ts index f612c1101..0cc10e303 100644 --- a/src/views/repo/router.ts +++ b/src/views/repo/router.ts @@ -2,6 +2,7 @@ import type { Config } from "@bindings/Config"; import type { Issue } from "@bindings/Issue"; import type { Patch } from "@bindings/Patch"; import type { RepoInfo } from "@bindings/RepoInfo"; +import type { Revision } from "@bindings/Revision"; import { invoke } from "@tauri-apps/api/core"; import { unreachable } from "@app/lib/utils"; @@ -42,6 +43,23 @@ export interface LoadedRepoIssuesRoute { export type PatchStatus = "all" | Patch["state"]["status"]; +export interface RepoPatchRoute { + resource: "repo.patch"; + rid: string; + patch: string; +} + +export interface LoadedRepoPatchRoute { + resource: "repo.patch"; + params: { + repo: RepoInfo; + config: Config; + patch: Patch; + patches: Patch[]; + revisions: Revision[]; + }; +} + export interface RepoPatchesRoute { resource: "repo.patches"; rid: string; @@ -58,12 +76,43 @@ export interface LoadedRepoPatchesRoute { }; } -export type RepoRoute = RepoIssueRoute | RepoIssuesRoute | RepoPatchesRoute; +export type RepoRoute = + | RepoIssueRoute + | RepoIssuesRoute + | RepoPatchRoute + | RepoPatchesRoute; export type LoadedRepoRoute = | LoadedRepoIssueRoute | LoadedRepoIssuesRoute + | LoadedRepoPatchRoute | LoadedRepoPatchesRoute; +export async function loadPatch( + route: RepoPatchRoute, +): Promise { + const repo: RepoInfo = await invoke("repo_by_id", { + rid: route.rid, + }); + const config: Config = await invoke("config"); + const patches: Patch[] = await invoke("list_patches", { + rid: route.rid, + status: "all", + }); + const patch: Patch = await invoke("patch_by_id", { + rid: route.rid, + id: route.patch, + }); + const revisions: Revision[] = await invoke("revisions_by_patch", { + rid: route.rid, + id: route.patch, + }); + + return { + resource: "repo.patch", + params: { repo, config, patch, patches, revisions }, + }; +} + export async function loadPatches( route: RepoPatchesRoute, ): Promise { @@ -82,24 +131,6 @@ export async function loadPatches( }; } -export async function loadIssues( - route: RepoIssuesRoute, -): Promise { - const repo: RepoInfo = await invoke("repo_by_id", { - rid: route.rid, - }); - const config: Config = await invoke("config"); - const issues: Issue[] = await invoke("list_issues", { - rid: route.rid, - status: route.status, - }); - - return { - resource: "repo.issues", - params: { repo, config, issues, status: route.status }, - }; -} - export async function loadIssue( route: RepoIssueRoute, ): Promise { @@ -122,6 +153,24 @@ export async function loadIssue( }; } +export async function loadIssues( + route: RepoIssuesRoute, +): Promise { + const repo: RepoInfo = await invoke("repo_by_id", { + rid: route.rid, + }); + const config: Config = await invoke("config"); + const issues: Issue[] = await invoke("list_issues", { + rid: route.rid, + status: route.status, + }); + + return { + resource: "repo.issues", + params: { repo, config, issues, status: route.status }, + }; +} + export function repoRouteToPath(route: RepoRoute): string { const pathSegments = ["/repos", route.rid]; @@ -136,6 +185,9 @@ export function repoRouteToPath(route: RepoRoute): string { url += `?${searchParams}`; } return url; + } else if (route.resource === "repo.patch") { + const url = [...pathSegments, "patches", route.patch].join("/"); + return url; } else if (route.resource === "repo.patches") { let url = [...pathSegments, "patches"].join("/"); const searchParams = new URLSearchParams(); @@ -174,16 +226,25 @@ export function repoUrlToRoute( } } } else if (resource === "patches") { - const status = searchParams.get("status"); - if ( - status === "draft" || - status === "open" || - status === "archived" || - status === "merged" - ) { - return { resource: "repo.patches", rid, status }; + const id = segments.shift(); + if (id) { + return { + resource: "repo.patch", + rid, + patch: id, + }; } else { - return { resource: "repo.patches", rid, status: "all" }; + const status = searchParams.get("status"); + if ( + status === "draft" || + status === "open" || + status === "archived" || + status === "merged" + ) { + return { resource: "repo.patches", rid, status }; + } else { + return { resource: "repo.patches", rid, status: "all" }; + } } } else { return null;