Radish alpha
r
rad:z4D5UCArafTzTQpDZNQRuqswh3ury
Radicle desktop app
Radicle
Git
Add Header component and other required components
Merged did:key:z6MkkfM3...sVz5 opened 1 year ago

Also uses svelte-routing as the router to be quicker in the beginning.

14 files changed +318 -2 0cab98ac 761c59e4
modified package-lock.json
@@ -26,6 +26,7 @@
        "svelte": "^4.2.18",
        "svelte-check": "^3.8.4",
        "svelte-eslint-parser": "^0.41.0",
+
        "svelte-routing": "^2.13.0",
        "tslib": "^2.6.3",
        "typescript": "^5.2.2",
        "typescript-eslint": "^7.17.0",
@@ -1076,6 +1077,17 @@
      "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
      "dev": true
    },
+
    "node_modules/@types/node": {
+
      "version": "22.5.0",
+
      "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.0.tgz",
+
      "integrity": "sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==",
+
      "dev": true,
+
      "optional": true,
+
      "peer": true,
+
      "dependencies": {
+
        "undici-types": "~6.19.2"
+
      }
+
    },
    "node_modules/@types/pug": {
      "version": "2.0.10",
      "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz",
@@ -3210,6 +3222,12 @@
        }
      }
    },
+
    "node_modules/svelte-routing": {
+
      "version": "2.13.0",
+
      "resolved": "https://registry.npmjs.org/svelte-routing/-/svelte-routing-2.13.0.tgz",
+
      "integrity": "sha512-/NTxqTwLc7Dq306hARJrH2HLXOBtKd7hu8nxgoFDlK0AC4SOKnzisiX/9m8Uksei1QAWtlAEdF91YphNM8iDMg==",
+
      "dev": true
+
    },
    "node_modules/text-table": {
      "version": "0.2.0",
      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -3309,6 +3327,14 @@
        }
      }
    },
+
    "node_modules/undici-types": {
+
      "version": "6.19.8",
+
      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
+
      "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
+
      "dev": true,
+
      "optional": true,
+
      "peer": true
+
    },
    "node_modules/uri-js": {
      "version": "4.4.1",
      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
modified package.json
@@ -34,6 +34,7 @@
    "svelte": "^4.2.18",
    "svelte-check": "^3.8.4",
    "svelte-eslint-parser": "^0.41.0",
+
    "svelte-routing": "^2.13.0",
    "tslib": "^2.6.3",
    "typescript": "^5.2.2",
    "typescript-eslint": "^7.17.0",
modified public/colors.css
@@ -1,4 +1,9 @@
:root {
  --color-background-default: #0a0d10;
  --color-foreground-contrast: #f9f9fb;
+
  --color-foreground-disabled: #6a6a81;
+
  --color-border-default: #2e2f38;
+
  --color-background-float: #14151a;
+
  --color-fill-float-hover: #1b1c22;
+
  --color-fill-ghost: #24252d;
}
modified public/typography.css
@@ -29,6 +29,7 @@
  --font-size-small: 0.875rem; /* 14px */
  --font-size-regular: 1rem; /* 16px */
  --font-size-medium: 1.25rem; /* 20px */
+
  --font-weight-semibold: 600;
}

html {
@@ -46,3 +47,7 @@ html {
.txt-medium {
  font-size: var(--font-size-medium);
}
+

+
.txt-semibold {
+
  font-weight: var(--font-weight-semibold) !important;
+
}
modified src/App.svelte
@@ -1,5 +1,11 @@
<script lang="ts">
-
  import Startup from "./views/Startup.svelte";
+
  import { Router, Route } from "svelte-routing";
+

+
  import Startup from "@app/views/Startup.svelte";
+
  import Repos from "@app/views/Repos.svelte";
</script>

-
<Startup />
+
<Router>
+
  <Route path="/" component={Startup} />
+
  <Route path="/repos" component={Repos} />
+
</Router>
added src/components/Header.svelte
@@ -0,0 +1,51 @@
+
<script lang="ts">
+
  import Background from "./Header/Background.svelte";
+
  import Icon from "./Icon.svelte";
+
  import Label from "./Label.svelte";
+
</script>
+

+
<style>
+
  .flex-item {
+
    display: flex;
+
    align-items: center;
+
  }
+
  header {
+
    padding: 0 0.5rem;
+
    gap: 1.5rem;
+
    height: 3rem;
+
  }
+
  .wrapper {
+
    width: 100%;
+
    justify-content: space-between;
+
    padding: 0 0.5rem;
+
  }
+
  .wrapper-left {
+
    gap: 0.5rem;
+
    padding: 0 0.5rem;
+
  }
+
</style>
+

+
<header class="flex-item">
+
  <div class="wrapper flex-item">
+
    <div class="wrapper-left flex-item">
+
      <div class="flex-item" style:gap="0.5rem">
+
        <Icon name="arrow-left" />
+
        <Icon name="arrow-right" />
+
      </div>
+
      <Label
+
        styleBorderColor="var(--color-fill-ghost)"
+
        styleFillColor="var(--color-fill-ghost)">
+
        Repositories
+
      </Label>
+
      <Label styleBorderColor="var(--color-fill-ghost)">
+
        <Icon name="plus" />
+
      </Label>
+
    </div>
+
    <div class="flex-item">
+
      <Label styleBorderColor="var(--color-fill-ghost)">
+
        <Icon name="offline" /> Offline
+
      </Label>
+
    </div>
+
  </div>
+
  <Background />
+
</header>
added src/components/Header/Background.svelte
@@ -0,0 +1,49 @@
+
<style>
+
  .container {
+
    height: 3rem;
+
    z-index: -1;
+
    position: absolute;
+
    top: 0;
+
    left: 0.5rem;
+
    right: 0.5rem;
+
    display: grid;
+
    grid-template-columns: repeat(3, 2px) auto repeat(3, 2px);
+
    grid-template-rows: auto repeat(3, 2px);
+
  }
+
  .bg {
+
    background-color: var(--color-background-float);
+
  }
+
</style>
+

+
<div class="container">
+
  <div class="bg"></div>
+
  <div class="bg"></div>
+
  <div class="bg"></div>
+
  <div class="bg"></div>
+
  <div class="bg"></div>
+
  <div class="bg"></div>
+
  <div class="bg"></div>
+
  <div></div>
+
  <div class="bg"></div>
+
  <div class="bg"></div>
+
  <div class="bg"></div>
+
  <div class="bg"></div>
+
  <div class="bg"></div>
+
  <div></div>
+

+
  <div></div>
+
  <div></div>
+
  <div class="bg"></div>
+
  <div class="bg"></div>
+
  <div class="bg"></div>
+
  <div></div>
+
  <div></div>
+

+
  <div></div>
+
  <div></div>
+
  <div></div>
+
  <div class="bg"></div>
+
  <div></div>
+
  <div></div>
+
  <div></div>
+
</div>
added src/components/Icon.svelte
@@ -0,0 +1,86 @@
+
<script lang="ts">
+
  import { unreachable } from "@app/lib/utils";
+
  export let name: "arrow-left" | "arrow-right" | "plus" | "offline";
+
</script>
+

+
<style>
+
  svg {
+
    display: flex;
+
    flex-shrink: 0;
+
  }
+
</style>
+

+
<!-- svelte-ignore a11y-click-events-have-key-events -->
+
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
+
<svg
+
  role="img"
+
  on:click
+
  width="16"
+
  height="16"
+
  fill="currentColor"
+
  viewBox="0 0 16 16">
+
  {#if name === "arrow-left"}
+
    <path d="M1.99997 7L1.99997 8L2.99997 8L2.99997 7L1.99997 7Z" />
+
    <path d="M2.99997 6L2.99997 7L3.99997 7L3.99997 6L2.99997 6Z" />
+
    <path d="M2.99997 9L2.99997 8L3.99997 8L3.99997 9L2.99997 9Z" />
+
    <path d="M2.99997 9L14 9L14 7L2.99997 7L2.99997 9Z" />
+
    <path d="M3.99997 11L4.99997 11L4.99997 5L3.99997 5L3.99997 11Z" />
+
    <path d="M4.99997 12L5.99997 12L5.99997 4L4.99997 4L4.99997 12Z" />
+
    <path d="M5.99997 13L6.99997 13L6.99997 3L5.99997 3L5.99997 13Z" />
+
    <path d="M2.99997 10L3.99997 10L3.99997 9L2.99997 9L2.99997 10Z" />
+
    <path d="M1.99997 9L2.99997 9L2.99997 8L1.99997 8L1.99997 9Z" />
+
  {:else if name === "arrow-right"}
+
    <path d="M14 9V8H13V9H14Z" />
+
    <path d="M13 10V9H12V10H13Z" />
+
    <path d="M13 7V8H12V7H13Z" />
+
    <path d="M13 7H2.00003V9H13V7Z" />
+
    <path d="M12 5H11V11H12V5Z" />
+
    <path d="M11 4H10V12H11V4Z" />
+
    <path d="M10 3H9.00003V13H10V3Z" />
+
    <path d="M13 6H12V7H13V6Z" />
+
    <path d="M14 7H13V8H14V7Z" />
+
  {:else if name === "plus"}
+
    <path d="M7.00002 2H9.00002V14H7.00002V2Z" />
+
    <path d="M14 7V9L2.00002 9L2.00002 7L14 7Z" />
+
  {:else if name === "offline"}
+
    <path d="M3 6L3 8H2L2 6H3Z" />
+
    <path d="M13 10V8H14V10H13Z" />
+
    <path d="M5 9V7H4V9H5Z" />
+
    <path d="M11 7V9H12V7H11Z" />
+
    <path d="M4 4L4 6H3L3 4H4Z" />
+
    <path d="M12 12V10H13V12H12Z" />
+
    <path d="M4 10V12H3L3 10H4Z" />
+
    <path d="M12 6V5H13V6H12Z" />
+
    <path d="M5 4H4V3L5 3V4Z" />
+
    <path d="M11 12H12V13H11V12Z" />
+
    <path d="M3 8L3 10H2L2 8H3Z" />
+
    <path d="M13 8V6H14V8H13Z" />
+
    <path d="M10 5L11 5V6L10 6V5Z" />
+
    <path d="M6 7H5L5 5H6V7Z" />
+
    <path d="M10 9L11 9V11H10V9Z" />
+
    <path d="M7 7H9V8H7V7Z" />
+
    <path d="M6 11H7V12H6V11Z" />
+
    <path d="M10 5H9V4H10V5Z" />
+
    <path d="M6 4H7V5H6L6 4Z" />
+
    <path d="M10 12H9V11H10V12Z" />
+
    <path d="M5 2H6V3L5 3L5 2Z" />
+
    <path d="M11 14H10V13H11V14Z" />
+
    <path d="M5 13H6V14H5V13Z" />
+
    <path d="M11 3L10 3V2L11 2V3Z" />
+
    <path d="M12 4H11V3L12 3V4Z" />
+
    <path d="M13 2.00001H14V3.00001H13V2.00001Z" />
+
    <path d="M12 3L13 3.00001V4.00001L12 4V3Z" />
+
    <path d="M11 4H12V5L11 5V4Z" />
+
    <path d="M10 5L11 5V6L10 6V5Z" />
+
    <path d="M9 6.00001L10 6L10 7.00001L9 7L9 6.00001Z" />
+
    <path d="M8 7.00001L9 7V8L8 8.00001V7.00001Z" />
+
    <path d="M7 8L8 8.00001V9.00001H7L7 8Z" />
+
    <path d="M6 9L7 9.00001V10H6V9Z" />
+
    <path d="M5 10H6V11L5 11V10Z" />
+
    <path d="M4 11L5 11V12L4 12L4 11Z" />
+
    <path d="M3 12H4L4 13H3L3 12Z" />
+
    <path d="M2 13L3 13L3 14H2V13Z" />
+
  {:else}
+
    {unreachable(name)}
+
  {/if}
+
</svg>
added src/components/Label.svelte
@@ -0,0 +1,67 @@
+
<script lang="ts">
+
  export let styleBorderColor: string;
+
  export let styleFillColor: string = "transparent";
+
  export let emptyPixels: 2 | 1 = 2;
+

+
  let gridTemplate = `${"2px ".repeat(emptyPixels)}auto ${"2px ".repeat(emptyPixels)}`;
+
</script>
+

+
<style>
+
  .content {
+
    padding: 2px 8px;
+
    display: flex;
+
    gap: 6px;
+
    align-items: center;
+
  }
+
  .container {
+
    white-space: nowrap;
+
    user-select: none;
+
    column-gap: 0;
+
    height: 2rem;
+
    row-gap: 0;
+
    display: grid;
+
  }
+
</style>
+

+
<div
+
  class="container"
+
  style:grid-template-columns={gridTemplate}
+
  style:grid-template-rows={gridTemplate}>
+
  {@html "<div></div>".repeat(emptyPixels)}
+
  <div style:background-color={styleBorderColor} />
+
  {@html "<div></div>".repeat(emptyPixels)}
+

+
  {#if emptyPixels === 2}
+
    <div />
+
    <div style:background-color={styleBorderColor} />
+
    <div style:background-color={styleFillColor} />
+
    <div style:background-color={styleBorderColor} />
+
    <div />
+
  {/if}
+

+
  <div style:background-color={styleBorderColor} />
+
  {#if emptyPixels === 2}
+
    <div style:background-color={styleFillColor} />
+
  {/if}
+
  <div
+
    class="content txt-semibold txt-small"
+
    style:background-color={styleFillColor}>
+
    <slot />
+
  </div>
+
  {#if emptyPixels === 2}
+
    <div style:background-color={styleFillColor} />
+
  {/if}
+
  <div style:background-color={styleBorderColor} />
+

+
  {#if emptyPixels === 2}
+
    <div />
+
    <div style:background-color={styleBorderColor} />
+
    <div style:background-color={styleFillColor} />
+
    <div style:background-color={styleBorderColor} />
+
    <div />
+
  {/if}
+

+
  {@html "<div></div>".repeat(emptyPixels)}
+
  <div style:background-color={styleBorderColor} />
+
  {@html "<div></div>".repeat(emptyPixels)}
+
</div>
added src/lib/utils.ts
@@ -0,0 +1,3 @@
+
export const unreachable = (value: never): never => {
+
  throw new Error(`Unreachable code: ${value}`);
+
};
added src/views/Repos.svelte
@@ -0,0 +1,5 @@
+
<script>
+
  import Header from "@app/components/Header.svelte";
+
</script>
+

+
<Header />
modified src/views/Startup.svelte
@@ -1,6 +1,8 @@
<script lang="ts">
  import { invoke } from "@tauri-apps/api/core";
  import { onMount } from "svelte";
+
  import { Link } from "svelte-routing";
+

  import warningIcon from "/images/warning.png";

  let loading = true;
@@ -35,5 +37,6 @@
    {/if}
  {:else if !loading}
    <p class="txt-medium">You are all set!</p>
+
    <Link to="/repos">Repos</Link>
  {/if}
</main>
modified tsconfig.json
@@ -20,6 +20,7 @@
    "skipLibCheck": true,
    "paths": {
      "@app/*": ["./src/*"],
+
      "@bindings/*": ["./src-tauri/bindings/*"],
      "@public/*": ["./public/*"]
    }
  }
modified vite.config.ts
@@ -1,5 +1,6 @@
import { defineConfig } from "vite";
import { svelte } from "@sveltejs/vite-plugin-svelte";
+
import path from "node:path";

// https://vitejs.dev/config/
export default defineConfig({
@@ -16,4 +17,11 @@ export default defineConfig({
      ignored: ["**/src-tauri/**"],
    },
  },
+
  resolve: {
+
    alias: {
+
      "@app": path.resolve("./src"),
+
      "@bindings": path.resolve("./src-tauri/bindings/"),
+
      "@public": path.resolve("./public"),
+
    },
+
  },
});