Radish alpha
r
rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5
Radicle web interface
Radicle
Git
Update schemas and usage of project payload
Sebastian Martinez committed 1 year ago
commit 6c2d1d755e09ed7f5a8737859faa6d9663b7c056
parent c798e5d
13 files changed +110 -67
modified http-client/lib/repo.ts
@@ -30,28 +30,34 @@ import { authorSchema } from "./shared.js";

const repoSchema = object({
  rid: string(),
-
  "xyz.radicle.project": object({
-
    name: string(),
-
    description: string(),
-
    defaultBranch: string(),
+
  payloads: object({
+
    "xyz.radicle.project": object({
+
      data: object({
+
        name: string(),
+
        description: string(),
+
        defaultBranch: string(),
+
      }),
+
      meta: object({
+
        head: string(),
+
        patches: object({
+
          open: number(),
+
          draft: number(),
+
          archived: number(),
+
          merged: number(),
+
        }),
+
        issues: object({
+
          open: number(),
+
          closed: number(),
+
        }),
+
      }),
+
    }),
  }),
  delegates: array(authorSchema),
-
  head: string(),
  threshold: number(),
  visibility: union([
    object({ type: literal("public") }),
    object({ type: literal("private"), allow: optional(array(string())) }),
  ]),
-
  patches: object({
-
    open: number(),
-
    draft: number(),
-
    archived: number(),
-
    merged: number(),
-
  }),
-
  issues: object({
-
    open: number(),
-
    closed: number(),
-
  }),
  seeding: number(),
});
const reposSchema = array(repoSchema);
modified src/components/RepoCard.svelte
@@ -17,7 +17,7 @@
  export let repoInfo: RepoInfo;

  $: repo = repoInfo.repo;
-
  $: project = repoInfo.repo["xyz.radicle.project"];
+
  $: project = repoInfo.repo.payloads["xyz.radicle.project"];
  $: baseUrl = repoInfo.baseUrl;
  $: isPrivate = repo.visibility.type === "private";
</script>
@@ -145,7 +145,7 @@
    </div>
    <div class="title">
      <div class="headline-and-badges">
-
        <h4 use:twemoji>{project.name}</h4>
+
        <h4 use:twemoji>{project.data.name}</h4>
        <div class="badges">
          {#if isPrivate}
            <div
@@ -166,19 +166,19 @@
        </div>
      </div>
      <p class="txt-small" use:twemoji>
-
        {project.description}
+
        {project.data.description}
      </p>
    </div>
    <div>
      <div class="stats-row txt-tiny" style:color="var(--color-foreground-dim)">
        <Icon name="issue" />
-
        {repo.issues.open} ·
+
        {project.meta.issues.open} ·
        <Icon name="patch" />
        <span
          style:overflow="hidden"
          style:text-overflow="ellipsis"
          title={absoluteTimestamp(repoInfo.lastCommit.commit.committer.time)}>
-
          {repo.patches.open} · Updated {formatTimestamp(
+
          {project.meta.patches.open} · Updated {formatTimestamp(
            repoInfo.lastCommit.commit.committer.time,
          )}
        </span>
modified src/components/RepoCard.ts
@@ -24,13 +24,18 @@ export async function fetchRepoInfos(
    repos = await api.repo.getAll(query);
  }
  const info = await Promise.all(
-
    repos.map(async repo => {
-
      const [activity, lastCommit] = await Promise.all([
-
        loadRepoActivity(repo.rid, baseUrl),
-
        api.repo.getCommitBySha(repo.rid, repo.head),
-
      ]);
-
      return { repo, activity, lastCommit, baseUrl };
-
    }),
+
    repos
+
      .filter(r => Boolean(r.payloads["xyz.radicle.project"]))
+
      .map(async repo => {
+
        const [activity, lastCommit] = await Promise.all([
+
          loadRepoActivity(repo.rid, baseUrl),
+
          api.repo.getCommitBySha(
+
            repo.rid,
+
            repo["payloads"]["xyz.radicle.project"].meta.head,
+
          ),
+
        ]);
+
        return { repo, activity, lastCommit, baseUrl };
+
      }),
  );

  return info.sort((a, b) => {
modified src/views/repos/Header.svelte
@@ -82,7 +82,7 @@
          class="counter"
          class:selected={activeTab === "issues"}
          class:hover={hover && activeTab !== "issues"}>
-
          {repo.issues.open}
+
          {repo.payloads["xyz.radicle.project"].meta.issues.open}
        </span>
      </div>
    </Button>
@@ -107,7 +107,7 @@
          class="counter"
          class:hover={hover && activeTab !== "patches"}
          class:selected={activeTab === "patches"}>
-
          {repo.patches.open}
+
          {repo.payloads["xyz.radicle.project"].meta.patches.open}
        </span>
      </div>
    </Button>
modified src/views/repos/Issue.svelte
@@ -215,7 +215,9 @@
            <Markdown
              breaks
              content={issue.discussion[0].body}
-
              rawPath={rawPath(repo.head)} />
+
              rawPath={rawPath(
+
                repo.payloads["xyz.radicle.project"].meta.head,
+
              )} />
          {:else}
            <span class="txt-missing">No description</span>
          {/if}
@@ -234,7 +236,9 @@
              <ThreadComponent
                {baseUrl}
                {thread}
-
                rawPath={rawPath(repo.head)} />
+
                rawPath={rawPath(
+
                  repo.payloads["xyz.radicle.project"].meta.head,
+
                )} />
              {#if i < threads.length - 1}
                <div class="connector" />
              {/if}
modified src/views/repos/Issues.svelte
@@ -72,7 +72,9 @@
  };

  $: showMoreButton =
-
    !loading && !error && allIssues.length < repo.issues[status];
+
    !loading &&
+
    !error &&
+
    allIssues.length < repo.payloads["xyz.radicle.project"].meta.issues[status];
</script>

<style>
@@ -146,7 +148,7 @@
        </div>
        {capitalize(status)}
        <div class="dropdown-button-counter">
-
          {repo.issues[status]}
+
          {repo.payloads["xyz.radicle.project"].meta.issues[status]}
        </div>
        <Icon name={expanded ? "chevron-up" : "chevron-down"} />
      </Button>
@@ -172,7 +174,7 @@
              <div
                class="dropdown-list-counter"
                class:selected={item === status}>
-
                {repo.issues[item]}
+
                {repo.payloads["xyz.radicle.project"].meta.issues[item]}
              </div>
            </div>
          </DropdownListItem>
@@ -201,7 +203,7 @@
      {error} />
  {/if}

-
  {#if repo.issues[status] === 0}
+
  {#if repo.payloads["xyz.radicle.project"].meta.issues[status] === 0}
    <div class="placeholder">
      <Placeholder iconName="no-issues" caption={`No ${status} issues`} />
    </div>
modified src/views/repos/Layout.svelte
@@ -134,7 +134,7 @@
              node: baseUrl,
            }}>
            <div class="breadcrumb">
-
              {repo["xyz.radicle.project"].name}
+
              {repo.payloads["xyz.radicle.project"].data.name}
            </div>
          </Link>
        </span>
@@ -191,7 +191,7 @@

      <div style:width="100%">
        <Link
-
          title={`${repo.issues.open} Issues`}
+
          title={`${repo.payloads["xyz.radicle.project"].meta.issues.open} Issues`}
          route={{
            resource: "repo.issues",
            repo: repo.rid,
@@ -207,7 +207,7 @@

      <div style:width="100%">
        <Link
-
          title={`${repo.patches.open} Patches`}
+
          title={`${repo.payloads["xyz.radicle.project"].meta.patches.open} Patches`}
          route={{
            resource: "repo.patches",
            repo: repo.rid,
modified src/views/repos/Patches.svelte
@@ -80,7 +80,10 @@
  };

  $: showMoreButton =
-
    !loading && !error && allPatches.length < repo.patches[status];
+
    !loading &&
+
    !error &&
+
    allPatches.length <
+
      repo.payloads["xyz.radicle.project"].meta.patches[status];
</script>

<style>
@@ -154,7 +157,7 @@
        </div>
        {capitalize(status)}
        <div class="dropdown-button-counter">
-
          {repo.patches[status]}
+
          {repo.payloads["xyz.radicle.project"].meta.patches[status]}
        </div>
        <Icon name={expanded ? "chevron-up" : "chevron-down"} />
      </Button>
@@ -179,7 +182,7 @@
              <div
                class="dropdown-list-counter"
                class:selected={item === status}>
-
                {repo.patches[item]}
+
                {repo.payloads["xyz.radicle.project"].meta.patches[item]}
              </div>
            </div>
          </DropdownListItem>
@@ -208,7 +211,7 @@
      {error} />
  {/if}

-
  {#if repo.patches[status] === 0}
+
  {#if repo.payloads["xyz.radicle.project"].meta.patches[status] === 0}
    <div class="placeholder">
      <Placeholder iconName="no-patches" caption={`No ${status} patches`} />
    </div>
modified src/views/repos/Sidebar.svelte
@@ -183,7 +183,7 @@
      </Button>
    </Link>
    <Link
-
      title={`${repo.issues.open} Issues`}
+
      title={`${repo.payloads["xyz.radicle.project"].meta.issues.open} Issues`}
      route={{
        resource: "repo.issues",
        repo: repo.rid,
@@ -203,14 +203,14 @@
            class="counter"
            class:selected={activeTab === "issues"}
            class:hover={hover && activeTab !== "issues"}>
-
            {repo.issues.open}
+
            {repo.payloads["xyz.radicle.project"].meta.issues.open}
          </span>
        </div>
      </Button>
    </Link>

    <Link
-
      title={`${repo.patches.open} Patches`}
+
      title={`${repo.payloads["xyz.radicle.project"].meta.patches.open} Patches`}
      route={{
        resource: "repo.patches",
        repo: repo.rid,
@@ -230,7 +230,7 @@
            class="counter"
            class:hover={hover && activeTab !== "patches"}
            class:selected={activeTab === "patches"}>
-
            {repo.patches.open}
+
            {repo.payloads["xyz.radicle.project"].meta.patches.open}
          </span>
        </div>
      </Button>
modified src/views/repos/Source/Header.svelte
@@ -36,12 +36,15 @@
  $: if (revision === lastCommit.id) {
    selectedBranch = undefined;
  } else {
-
    selectedBranch = revision || repo["xyz.radicle.project"].defaultBranch;
+
    selectedBranch =
+
      revision || repo.payloads["xyz.radicle.project"].data.defaultBranch;
  }

  $: lastCommit = tree.lastCommit;
  $: onCanonical = Boolean(
-
    !peer && selectedBranch === repo["xyz.radicle.project"].defaultBranch,
+
    !peer &&
+
      selectedBranch ===
+
        repo.payloads["xyz.radicle.project"].data.defaultBranch,
  );
  $: if (onCanonical) {
    commitButtonVariant = "right";
modified src/views/repos/Source/PeerBranchSelector.svelte
@@ -37,8 +37,8 @@
  const searchElements = [
    {
      peer: undefined,
-
      revision: repo["xyz.radicle.project"].defaultBranch,
-
      head: repo.head,
+
      revision: repo.payloads["xyz.radicle.project"].data.defaultBranch,
+
      head: repo.payloads["xyz.radicle.project"].meta.head,
    },
    ...peers.flatMap(peer =>
      Object.entries(peer.heads).map(([name, head]) => ({
@@ -252,7 +252,7 @@
              style={`${subgridStyle} gap: inherit;`}>
              <div class="global-flex-item">
                <Icon name="branch" />
-
                {repo["xyz.radicle.project"].defaultBranch}
+
                {repo.payloads["xyz.radicle.project"].data.defaultBranch}
                <Badge title="Canonical branch" variant="foreground-emphasized">
                  Canonical
                </Badge>
@@ -260,7 +260,7 @@
              <div
                class="txt-monospace"
                style="color: var(--color-foreground-dim);">
-
                {formatCommit(repo.head)}
+
                {formatCommit(repo.payloads["xyz.radicle.project"].meta.head)}
              </div>
            </DropdownListItem>
          </Link>
modified src/views/repos/Source/RepoNameHeader.svelte
@@ -22,7 +22,7 @@
    );
  }

-
  $: project = repo["xyz.radicle.project"];
+
  $: project = repo.payloads["xyz.radicle.project"];
</script>

<style>
@@ -73,7 +73,7 @@
          node: baseUrl,
        }}>
        <span class="repo-name">
-
          {project.name}
+
          {project.data.name}
        </span>
      </Link>
    </span>
@@ -89,7 +89,7 @@
        style:display="flex"
        style:gap="0.5rem"
        class="global-hide-on-mobile-down">
-
        <CloneButton {baseUrl} id={repo.rid} name={project.name} />
+
        <CloneButton {baseUrl} id={repo.rid} name={project.data.name} />
        <SeedButton seedCount={repo.seeding} repoId={repo.rid} />
      </div>
      <div
@@ -105,5 +105,5 @@
  </div>
</div>
<div class="description" use:twemoji>
-
  {@html render(project.description)}
+
  {@html render(project.data.description)}
</div>
modified src/views/repos/router.ts
@@ -425,8 +425,15 @@ async function loadTreeView(
    nodePromise,
  ]);

+
  if (!repo["payloads"]["xyz.radicle.project"]) {
+
    throw new Error(
+
      `Repository ${repo.rid} does not have a xyz.radicle.project payload.`,
+
    );
+
  }
+

+
  const project = repo["payloads"]["xyz.radicle.project"];
  let branchMap: Record<string, string> = {
-
    [repo["xyz.radicle.project"].defaultBranch]: repo.head,
+
    [project.data.defaultBranch]: project.meta.head,
  };
  if (route.peer) {
    const peer = peers.find(peer => peer.id === route.peer);
@@ -448,7 +455,7 @@ async function loadTreeView(

  const commit = parseRevisionToOid(
    route.revision,
-
    repo["xyz.radicle.project"].defaultBranch,
+
    project.data.defaultBranch,
    branchMap,
  );
  const path = route.path || "/";
@@ -561,14 +568,20 @@ async function loadHistoryView(
    nodePromise,
  ]);

+
  if (!repo["payloads"]["xyz.radicle.project"]) {
+
    throw new Error(
+
      `Repository ${repo.rid} does not have a xyz.radicle.project payload.`,
+
    );
+
  }
+

+
  const project = repo["payloads"]["xyz.radicle.project"];
  let commitId;
  if (route.revision && isOid(route.revision)) {
    commitId = route.revision;
  } else if (branchMap) {
-
    commitId =
-
      branchMap[route.revision || repo["xyz.radicle.project"].defaultBranch];
+
    commitId = branchMap[route.revision || project.data.defaultBranch];
  } else if (!route.revision) {
-
    commitId = repo.head;
+
    commitId = project.meta.head;
  }

  if (!commitId) {
@@ -1016,28 +1029,35 @@ function patchRouteToPath(route: RepoPatchRoute): string {
export function repoTitle(loadedRoute: RepoLoadedRoute) {
  const title: string[] = [];

+
  if (!loadedRoute.params.repo["payloads"]["xyz.radicle.project"]) {
+
    throw new Error(
+
      `Repository ${loadedRoute.params.repo.rid} does not have a xyz.radicle.project payload.`,
+
    );
+
  }
+
  const project = loadedRoute.params.repo["payloads"]["xyz.radicle.project"];
+

  if (loadedRoute.resource === "repo.source") {
-
    title.push(loadedRoute.params.repo["xyz.radicle.project"].name);
-
    if (loadedRoute.params.repo["xyz.radicle.project"].description.length > 0) {
-
      title.push(loadedRoute.params.repo["xyz.radicle.project"].description);
+
    title.push(project.data.name);
+
    if (project.data.description.length > 0) {
+
      title.push(project.data.description);
    }
  } else if (loadedRoute.resource === "repo.commit") {
    title.push(loadedRoute.params.commit.commit.summary);
    title.push("commit");
  } else if (loadedRoute.resource === "repo.history") {
-
    title.push(loadedRoute.params.repo["xyz.radicle.project"].name);
+
    title.push(project.data.name);
    title.push("history");
  } else if (loadedRoute.resource === "repo.issue") {
    title.push(loadedRoute.params.issue.title);
    title.push("issue");
  } else if (loadedRoute.resource === "repo.issues") {
-
    title.push(loadedRoute.params.repo["xyz.radicle.project"].name);
+
    title.push(project.data.name);
    title.push("issues");
  } else if (loadedRoute.resource === "repo.patch") {
    title.push(loadedRoute.params.patch.title);
    title.push("patch");
  } else if (loadedRoute.resource === "repo.patches") {
-
    title.push(loadedRoute.params.repo["xyz.radicle.project"].name);
+
    title.push(project.data.name);
    title.push("patches");
  } else {
    return unreachable(loadedRoute);