diff --git a/public/index.css b/public/index.css index 8c61e4d..9ba95fa 100644 --- a/public/index.css +++ b/public/index.css @@ -34,3 +34,96 @@ body { align-items: center; gap: 0.5rem; } + +.global-tab { + padding-left: 0.5rem; + border-left: 1px solid var(--color-fill-ghost-hover); + margin-left: 1rem; + flex-direction: column; + justify-content: space-between; + align-items: flex-start; + column-gap: 0.5rem; +} + +.global-counter { + display: flex; + align-items: center; + justify-content: center; + background-color: var(--color-fill-ghost-hover); + clip-path: var(--1px-corner-fill); + height: 1.5rem; + padding: 0 0.5rem; + min-width: 1.5rem; +} + +:root { + --1px-corner-fill: polygon( + 0 2px, + 2px 2px, + 2px 0, + calc(100% - 2px) 0, + calc(100% - 2px) 2px, + 100% 2px, + 100% calc(100% - 2px), + calc(100% - 2px) calc(100% - 2px), + calc(100% - 2px) calc(100% - 2px), + calc(100% - 2px) 100%, + 2px 100%, + 2px calc(100% - 2px), + 0 calc(100% - 2px) + ); + + --2px-corner-fill: polygon( + 0 4px, + 2px 4px, + 2px 2px, + 4px 2px, + 4px 0, + calc(100% - 4px) 0, + calc(100% - 4px) 2px, + calc(100% - 2px) 2px, + calc(100% - 2px) 4px, + 100% 4px, + 100% calc(100% - 4px), + calc(100% - 2px) calc(100% - 4px), + calc(100% - 2px) calc(100% - 2px), + calc(100% - 4px) calc(100% - 2px), + calc(100% - 4px) 100%, + 4px 100%, + 4px calc(100% - 2px), + 2px calc(100% - 2px), + 2px calc(100% - 4px), + 0 calc(100% - 4px) + ); + + --3px-corner-fill: polygon( + 0 6px, + 2px 6px, + 2px 4px, + 4px 4px, + 4px 2px, + 6px 2px, + 6px 0, + calc(100% - 6px) 0, + calc(100% - 6px) 2px, + calc(100% - 4px) 2px, + calc(100% - 4px) 4px, + calc(100% - 2px) 4px, + calc(100% - 2px) 6px, + 100% 6px, + 100% calc(100% - 6px), + calc(100% - 2px) calc(100% - 6px), + calc(100% - 2px) calc(100% - 4px), + calc(100% - 4px) calc(100% - 4px), + calc(100% - 4px) calc(100% - 2px), + calc(100% - 6px) calc(100% - 2px), + calc(100% - 6px) 100%, + 6px 100%, + 6px calc(100% - 2px), + 4px calc(100% - 2px), + 4px calc(100% - 4px), + 2px calc(100% - 4px), + 2px calc(100% - 6px), + 0 calc(100% - 6px) + ); +} diff --git a/src/components/Avatar.svelte b/src/components/Avatar.svelte index 70bdd72..a3cb2c0 100644 --- a/src/components/Avatar.svelte +++ b/src/components/Avatar.svelte @@ -23,22 +23,7 @@ background-repeat: no-repeat; width: 1rem; height: 1rem; - clip-path: polygon( - 0 2px, - 2px 2px, - 2px 0, - calc(100% - 2px) 0, - calc(100% - 2px) 2px, - 100% 2px, - 100% calc(100% - 2px), - calc(100% - 2px) calc(100% - 2px), - calc(100% - 2px) calc(100% - 2px), - calc(100% - 2px) 100%, - 2px 100%, - 2px calc(100% - 2px), - 0 calc(100% - 2px) - ); - background-color: red; + clip-path: var(--1px-corner-fill); } diff --git a/src/components/Fill.svelte b/src/components/Fill.svelte deleted file mode 100644 index f061dcd..0000000 --- a/src/components/Fill.svelte +++ /dev/null @@ -1,106 +0,0 @@ - - - - - -
-
-
-
- -
-
- -
-
- -
-
-
-
diff --git a/src/components/Icon.svelte b/src/components/Icon.svelte index b9d7a7b..211b82b 100644 --- a/src/components/Icon.svelte +++ b/src/components/Icon.svelte @@ -24,6 +24,7 @@ | "plus" | "repo" | "seedling" + | "seedling-filled" | "settings" | "sidebar" | "sun" @@ -355,6 +356,35 @@ + {:else if name === "seedling-filled"} + + + + + + + + + + + + + + + + + + + + + + + + + + + + {:else if name === "settings"} diff --git a/src/components/Link.svelte b/src/components/Link.svelte index 3519ef9..9c6b7da 100644 --- a/src/components/Link.svelte +++ b/src/components/Link.svelte @@ -5,6 +5,7 @@ export let route: Route; export let disabled: boolean = false; + export let variant: "active" | "regular" | "tab" = "regular"; function navigateToRoute(event: MouseEvent): void { event.preventDefault(); @@ -21,13 +22,41 @@ color: var(--color-foreground-contrast); text-decoration: none; } - a:hover { + .regular:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px; } + + .tab { + display: flex; + width: 100%; + justify-content: space-between; + align-items: center; + padding: 4px 4px 4px 10px; + clip-path: var(--2px-corner-fill); + } + + .tab:hover { + background-color: var(--color-fill-ghost); + } + + .active { + background-color: var(--color-fill-ghost); + display: flex; + width: 100%; + justify-content: space-between; + align-items: center; + padding: 4px 4px 4px 10px; + clip-path: var(--2px-corner-fill); + } - + diff --git a/src/components/RepoHeader.svelte b/src/components/RepoHeader.svelte index f763999..25af488 100644 --- a/src/components/RepoHeader.svelte +++ b/src/components/RepoHeader.svelte @@ -1,7 +1,6 @@ -
- - { - storeTheme("dark"); - }}> + + + + - { - storeTheme("light"); - }}> - - - Light - - - -
+ + diff --git a/src/lib/router/definitions.ts b/src/lib/router/definitions.ts index baff4e2..77ccedb 100644 --- a/src/lib/router/definitions.ts +++ b/src/lib/router/definitions.ts @@ -1,6 +1,11 @@ import type { Config } from "@bindings/Config"; import type { RepoInfo } from "@bindings/RepoInfo"; -import type { LoadedRepoRoute, RepoRoute } from "@app/views/repo/router"; +import type { + RepoIssuesRoute, + RepoPatchesRoute, + LoadedRepoIssuesRoute, + LoadedRepoPatchesRoute, +} from "@app/views/repo/router"; import { invoke } from "@tauri-apps/api/core"; @@ -31,13 +36,15 @@ export type Route = | AuthenticationErrorRoute | BootingRoute | HomeRoute - | RepoRoute; + | RepoIssuesRoute + | RepoPatchesRoute; export type LoadedRoute = | AuthenticationErrorRoute | BootingRoute | LoadedHomeRoute - | LoadedRepoRoute; + | LoadedRepoIssuesRoute + | LoadedRepoPatchesRoute; export async function loadRoute( route: Route, diff --git a/src/lib/utils.ts b/src/lib/utils.ts index e24d800..735eba4 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -34,6 +34,10 @@ export function truncateId(pubkey: string): string { return `${pubkey.substring(0, 6)}…${pubkey.slice(-6)}`; } +export function formatOid(id: string): string { + return id.substring(0, 7); +} + export const formatTimestamp = ( timestamp: number, current = new Date().getTime(), diff --git a/src/views/Home.svelte b/src/views/Home.svelte index baf218b..006202a 100644 --- a/src/views/Home.svelte +++ b/src/views/Home.svelte @@ -30,36 +30,7 @@ background-position: center; background-size: cover; height: 9.5rem; - clip-path: polygon( - 0 6px, - 2px 6px, - 2px 4px, - 4px 4px, - 4px 2px, - 6px 2px, - 6px 0, - calc(100% - 6px) 0, - calc(100% - 6px) 2px, - calc(100% - 4px) 2px, - calc(100% - 4px) 4px, - calc(100% - 2px) 4px, - calc(100% - 2px) 6px, - 100% 6px, - 100% calc(100% - 6px), - calc(100% - 2px) calc(100% - 6px), - calc(100% - 2px) calc(100% - 4px), - calc(100% - 4px) calc(100% - 4px), - calc(100% - 4px) calc(100% - 2px), - calc(100% - 6px) calc(100% - 2px), - calc(100% - 6px) 100%, - 6px 100%, - 6px calc(100% - 2px), - 4px calc(100% - 2px), - 4px calc(100% - 4px), - 2px calc(100% - 4px), - 2px calc(100% - 6px), - 0 calc(100% - 6px) - ); + clip-path: var(--3px-corner-fill); } diff --git a/src/views/repo/Issues.svelte b/src/views/repo/Issues.svelte index 6855b77..37b774d 100644 --- a/src/views/repo/Issues.svelte +++ b/src/views/repo/Issues.svelte @@ -1,8 +1,11 @@ - + + + - - {project.data.name} + +
+ + {project.data.name} +
+ Issues
-
-    
+  
+    
+ +
Issues
+
+ {project.meta.issues.open + project.meta.issues.closed} +
+ +
+
+ + Open +
+ {project.meta.issues.open} +
+ + + Closed +
+ {project.meta.issues.closed} +
+ +
+ +
+ +
Patches
+
+ {project.meta.patches.draft + + project.meta.patches.open + + project.meta.patches.archived + + project.meta.patches.merged} +
+ +
+
+ +
{#each issues as issue} - - {issue.title} - {:else} - No issues. +
+
+ +
+
{formatOid(issue.id)}
+ {issue.title} +
{/each} -
+ + {#if issues.length === 0} + {#if status === "all"} + No issues. + {:else} + No {status} issues. + {/if} + {/if} +
diff --git a/src/views/repo/Layout.svelte b/src/views/repo/Layout.svelte index b67a46d..2f521cb 100644 --- a/src/views/repo/Layout.svelte +++ b/src/views/repo/Layout.svelte @@ -1,27 +1,58 @@ -
+
- + { + hidden = !hidden; + }}> @@ -34,27 +65,19 @@
- Issues - - Open - - - Closed - - -
- Patches - - Draft - - - Open - - - Archived - - - Merged - - + + +
+ +
diff --git a/src/views/repo/Patches.svelte b/src/views/repo/Patches.svelte index 25f2fe9..c250db4 100644 --- a/src/views/repo/Patches.svelte +++ b/src/views/repo/Patches.svelte @@ -1,8 +1,11 @@ - + + + - - {project.data.name} + +
+ + {project.data.name} +
+ Patches
-
-    
+
+  
+    
+ +
Issues
+
+ {project.meta.issues.open + project.meta.issues.closed} +
+ +
+
+ +
Patches
+
+ {project.meta.patches.draft + + project.meta.patches.open + + project.meta.patches.archived + + project.meta.patches.merged} +
+ +
+
+ + Draft
+ {project.meta.patches.draft} +
+ + + Open
+ {project.meta.patches.open} +
+ + + Archived
+ {project.meta.patches.archived} +
+ + + Merged
+ {project.meta.patches.merged} +
+ +
+
+ +
{#each patches as patch} - - {patch.title} - {:else} - No patches. +
+
+ +
+
{formatOid(patch.id)}
+ {patch.title} +
{/each} -
+ + {#if patches.length === 0} + {#if status === "all"} + No patches. + {:else} + No {status} patches. + {/if} + {/if} +
diff --git a/src/views/repo/router.ts b/src/views/repo/router.ts index e75a31b..19f2080 100644 --- a/src/views/repo/router.ts +++ b/src/views/repo/router.ts @@ -6,32 +6,48 @@ import type { RepoInfo } from "@bindings/RepoInfo"; import { invoke } from "@tauri-apps/api/core"; import { unreachable } from "@app/lib/utils"; +export type IssueStatus = "all" | Issue["state"]["status"]; + export interface RepoIssuesRoute { resource: "repo.issues"; rid: string; - status?: "open" | "closed"; + status: IssueStatus; } export interface LoadedRepoIssuesRoute { resource: "repo.issues"; - params: { repo: RepoInfo; config: Config; issues: Issue[] }; + params: { + repo: RepoInfo; + config: Config; + issues: Issue[]; + status: IssueStatus; + }; } +export type PatchStatus = "all" | Patch["state"]["status"]; + export interface RepoPatchesRoute { resource: "repo.patches"; rid: string; - status?: "draft" | "open" | "archived" | "merged"; + status: PatchStatus; } export interface LoadedRepoPatchesRoute { resource: "repo.patches"; - params: { repo: RepoInfo; config: Config; patches: Patch[] }; + params: { + repo: RepoInfo; + config: Config; + patches: Patch[]; + status: PatchStatus; + }; } export type RepoRoute = RepoIssuesRoute | RepoPatchesRoute; export type LoadedRepoRoute = LoadedRepoIssuesRoute | LoadedRepoPatchesRoute; -export async function loadPatches(route: RepoRoute): Promise { +export async function loadPatches( + route: RepoPatchesRoute, +): Promise { const repo: RepoInfo = await invoke("repo_by_id", { rid: route.rid, }); @@ -41,10 +57,15 @@ export async function loadPatches(route: RepoRoute): Promise { status: route.status, }); - return { resource: "repo.patches", params: { repo, config, patches } }; + return { + resource: "repo.patches", + params: { repo, config, patches, status: route.status }, + }; } -export async function loadIssues(route: RepoRoute): Promise { +export async function loadIssues( + route: RepoIssuesRoute, +): Promise { const repo: RepoInfo = await invoke("repo_by_id", { rid: route.rid, }); @@ -54,7 +75,10 @@ export async function loadIssues(route: RepoRoute): Promise { status: route.status, }); - return { resource: "repo.issues", params: { repo, config, issues } }; + return { + resource: "repo.issues", + params: { repo, config, issues, status: route.status }, + }; } export function repoRouteToPath(route: RepoRoute): string { @@ -94,7 +118,7 @@ export function repoUrlToRoute( if (status === "open" || status === "closed") { return { resource: "repo.issues", rid, status }; } else { - return { resource: "repo.issues", rid }; + return { resource: "repo.issues", rid, status: "all" }; } } else if (resource === "patches") { const status = searchParams.get("status"); @@ -106,7 +130,7 @@ export function repoUrlToRoute( ) { return { resource: "repo.patches", rid, status }; } else { - return { resource: "repo.patches", rid }; + return { resource: "repo.patches", rid, status: "all" }; } } else { return null;