Radish alpha
r
Radicle web interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
Add verified badge to commit listing
Sebastian Martinez committed 4 years ago
commit 9620a171671bdee53325876564e65da57c458e1a
parent 9cd353282bec77fef5dd56227173fc675d2363ce
6 files changed +191 -67
added cypress/fixtures/groupedCommits.json
@@ -0,0 +1,42 @@
+
[
+
  {
+
    "groupDate": "Thursday, March 3, 2022",
+
    "commits": [
+
      {
+
        "sha": "9cd3532",
+
        "summary": "Second commit",
+
        "description": "",
+
        "committer": {
+
          "name": "dabit3",
+
          "mail": "dabit3@gmail.com"
+
        },
+
        "committerTime": "Thu, 03 Mar 2022 05:51:25 GMT"
+
      }
+
    ]
+
  },
+
  {
+
    "groupDate": "Wednesday, March 2, 2022",
+
    "commits": [
+
      {
+
        "sha": "e045b92",
+
        "summary": "Update README",
+
        "description": "",
+
        "committer": {
+
          "name": "dabit3",
+
          "mail": "dabit3@gmail.com"
+
        },
+
        "committerTime": "Wed, 02 Mar 2022 16:14:45 GMT"
+
      },
+
      {
+
        "sha": "cbf5df4",
+
        "summary": "initial commit",
+
        "description": "this is the first commit of many",
+
        "committer": {
+
          "name": "dabit3",
+
          "mail": "dabit3@gmail.com"
+
        },
+
        "committerTime": "Wed, 02 Mar 2022 15:58:05 GMT"
+
      }
+
    ]
+
  }
+
]
modified cypress/fixtures/projectCommits.json
@@ -1,18 +1,69 @@
{
  "headers": [
    {
-
      "sha1": "cbf5df499ab4f4a908f1756fbe2c236a4530516a",
-
      "author": {
-
        "name": "dabit3",
-
        "email": "dabit3@gmail.com"
+
      "header": {
+
        "sha1": "cbf5df499ab4f4a908f1756fbe2c236a4530516a",
+
        "author": {
+
          "name": "dabit3",
+
          "email": "dabit3@gmail.com"
+
        },
+
        "summary": "initial commit",
+
        "description": "",
+
        "committer": {
+
          "name": "dabit3",
+
          "email": "dabit3@gmail.com"
+
        },
+
        "committerTime": 1646236685
      },
-
      "summary": "initial commit",
-
      "description": "",
-
      "committer": {
-
        "name": "dabit3",
-
        "email": "dabit3@gmail.com"
+
      "context": {
+
        "committer": {
+
          "peer": {
+
            "id": "hyyg555wwkkutaysg6yr67qnu5d5ji54iur3n5uzzszndh8dp7ofue",
+
            "person": {
+
              "name": "sebastinez"
+
            },
+
            "delegate": true
+
          }
+
        }
+
      }
+
    },
+
    {
+
      "header": {
+
        "sha1": "e045b92297d21a709f3dea84d692c482ee61f6b2",
+
        "author": {
+
          "name": "dabit3",
+
          "email": "dabit3@gmail.com"
+
        },
+
        "summary": "Update README",
+
        "description": "",
+
        "committer": {
+
          "name": "dabit3",
+
          "email": "dabit3@gmail.com"
+
        },
+
        "committerTime": 1646237685
+
      },
+
      "context": {
+
        "committer": null
+
      }
+
    },
+
    {
+
      "header": {
+
        "sha1": "9cd353282bec77fef5dd56227173fc675d2363ce",
+
        "author": {
+
          "name": "dabit3",
+
          "email": "dabit3@gmail.com"
+
        },
+
        "summary": "Second commit",
+
        "description": "",
+
        "committer": {
+
          "name": "dabit3",
+
          "email": "dabit3@gmail.com"
+
        },
+
        "committerTime": 1646286685
      },
-
      "committerTime": 1646236685
+
      "context": {
+
        "committer": null
+
      }
    }
  ],
  "stats": {
modified cypress/integration/project.spec.ts
@@ -77,39 +77,47 @@ describe("Project View", () => {
    });
    cy.get("div.stat.commit-count").should("have.class", "active");

-
    cy.log("Commit Group");
-
    cy.get("header.commit-date").should("have.text", "Wednesday, March 2, 2022");
+
    cy.log("Commit Group & Commit Trailer");
+
    cy.fixture("groupedCommits.json").then((commitGroup) => {
+
      // This iterates over the commit groups and then over each commit.
+
      cy.get("div.commit-group").should("have.length", 2)
+
        .each((item, index) => {
+
          expect(Cypress.$(item.children(".commit-date")).text()).to.eq(commitGroup[index].groupDate);
+
          const $el = Cypress.$(item.find(".commit"));
+
          cy.wrap($el).each((commit, commitIndex) => {
+
            expect(Cypress.$(commit).find(".hash").text()).to.eq(commitGroup[index].commits[commitIndex].sha);
+
            expect(Cypress.$(commit).find("span.summary").text()).to.eq(commitGroup[index].commits[commitIndex].summary);
+
            expect(Cypress.$(commit).find(".author").text()).to.eq(commitGroup[index].commits[commitIndex].committer.name);
+
            expect(Cypress.$(commit).find(".time").text()).to.eq(commitGroup[index].commits[commitIndex].committerTime);
+
          });
+
        });

-
    cy.log("Commit Trailer");
-
    cy.get("div.summary span.hash")
-
      .should("have.text", "cbf5df4")
-
      .next()
-
      .should("have.text", "initial commit");
-
    cy.get("div.commit div.right span")
-
      .first()
-
      .should("have.text", "dabit3")
-
      .next()
-
      .should("have.text", "Wed, 02 Mar 2022 15:58:05 GMT");
-
    cy.get("div.summary").click();
+
      // Checking that the initial commit has the Verified badge
+
      cy.get(".badge").last().should("have.text", "Verified");
+
      cy.get("div.summary").last().click();

-
    cy.log("Commit Detail View");
-
    cy.location().should((location) => {
-
      expect(location.pathname).to.eq('/seeds/willow.radicle.garden/rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy/remotes/hyndc7nx9keq76p1bkw9831arcndeeu3trwsc7kxt3osmpi6j9oeke/commits/cbf5df499ab4f4a908f1756fbe2c236a4530516a');
+
      cy.log("Commit Detail View");
+
      // We get the initial commit from the fixture file to assert here
+
      const { committer, committerTime, summary, description } = commitGroup[1].commits[1];
+

+
      cy.location().should((location) => {
+
        expect(location.pathname).to.eq('/seeds/willow.radicle.garden/rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy/remotes/hyndc7nx9keq76p1bkw9831arcndeeu3trwsc7kxt3osmpi6j9oeke/commits/cbf5df499ab4f4a908f1756fbe2c236a4530516a');
+
      });
+
      cy.get("header div.summary h3").should("have.text", summary);
+
      cy.get("header pre.description").should("have.text", description);
+
      cy.get("header div.meta")
+
        .first()
+
        .should("have.text", `Committed by ${committer.name} <${committer.mail}> ${committerTime}`)
+
        .next()
+
        .should("have.text", `Authored by ${committer.name} <${committer.mail}>`);
+
      cy.get("div.changeset-summary").should("have.text", "1 file(s) changed\n    with\n    0 addition(s)\n    and\n    0 deletion(s)");
+
      cy.get("header.file-header:nth-child(1) div.file-data > *")
+
        .first()
+
        .should("have.text", "README.md")
+
        .next()
+
        .should("have.text", "created");
+
      cy.get("tr.diff-line td.diff-line-number").contains("16");
+
      cy.get("tr.diff-line td.diff-line-content").contains("To prevent front-running, the RAD/USDC balances are set through the Uniswap router *proxy* contract");
    });
-
    cy.get("header div.summary h3").should("have.text", "initial commit");
-
    cy.get("header pre.description").should("have.text", "this is the first commit of many");
-
    cy.get("header div.meta")
-
      .first()
-
      .should("have.text", "Committed by dabit3 <dabit3@gmail.com> Wed, 02 Mar 2022 15:58:05 GMT")
-
      .next()
-
      .should("have.text", "Authored by dabit3 <dabit3@gmail.com>");
-
    cy.get("div.changeset-summary").should("have.text", "1 file(s) changed\n    with\n    0 addition(s)\n    and\n    0 deletion(s)");
-
    cy.get("header.file-header:nth-child(1) div.file-data > *")
-
      .first()
-
      .should("have.text", "README.md")
-
      .next()
-
      .should("have.text", "created");
-
    cy.get("tr.diff-line td.diff-line-number").contains("16");
-
    cy.get("tr.diff-line td.diff-line-content").contains("To prevent front-running, the RAD/USDC balances are set through the Uniswap router *proxy* contract");
  });
});
modified src/base/projects/Commit/CommitTeaser.svelte
@@ -1,11 +1,18 @@
<script lang="ts">
  import Icon from "@app/Icon.svelte";
-
  import type { CommitHeader } from "@app/commit";
+
  import type { CommitHeaderWithContext } from "@app/commit";
+
  import type { Project } from "@app/project";
  import { formatCommit } from "@app/utils";
  import { createEventDispatcher } from "svelte";
+
  import { ProjectContent } from "@app/project";
  import { formatCommitTime } from "@app/commit";

-
  export let commit: CommitHeader;
+
  export let commit: CommitHeaderWithContext;
+
  export let project: Project;
+

+
  const navigateHistory = (revision: string, content?: ProjectContent) => {
+
    project.navigateTo({ content, revision, path: null });
+
  };

  const dispatch = createEventDispatcher();

@@ -62,14 +69,17 @@
  }
</style>

-
<div class="commit">
+
<div class="commit" on:click={() => navigateHistory(commit.header.sha1, ProjectContent.Commit)}>
  <div class="summary">
-
    <span class="secondary hash">{formatCommit(commit.sha1)}</span>
-
    <span>{commit.summary}</span>
+
    <span class="secondary hash">{formatCommit(commit.header.sha1)}</span>
+
    <span class="summary">{commit.header.summary}</span>
  </div>
  <div class="right">
-
    <span class="desktop-inline bold author">{commit.committer.name}</span>
-
    <span class="desktop-inline font-mono text-small time">{formatCommitTime(commit.committerTime)}</span>
-
    <Icon name="browse" width={17} inline fill on:click={() => browseCommit(commit.sha1)} />
+
    {#if commit.context.committer}
+
      <span class="badge primary">Verified</span>
+
    {/if}
+
    <span class="desktop-inline bold author">{commit.header.committer.name}</span>
+
    <span class="desktop-inline font-mono text-small time">{formatCommitTime(commit.header.committerTime)}</span>
+
    <Icon name="browse" width={17} inline fill on:click={() => browseCommit(commit.header.sha1)} />
  </div>
</div>
modified src/base/projects/History.svelte
@@ -1,16 +1,12 @@
<script lang="ts">
  import CommitTeaser from "./Commit/CommitTeaser.svelte";
  import type { Project } from "@app/project";
-
  import { ProjectContent } from "@app/project";
  import Loading from "@app/Loading.svelte";
  import { groupCommitHistory, GroupedCommitsHistory } from "@app/commit";

  export let project: Project;
  export let commit: string;

-
  const navigateHistory = (revision: string, content?: ProjectContent) => {
-
    project.navigateTo({ content, revision, path: null });
-
  };
  const fetchCommits = async (parentCommit: string): Promise<GroupedCommitsHistory> => {
    const commitsQuery = await project.getCommits(parentCommit);
    return groupCommitHistory(commitsQuery);
@@ -30,18 +26,18 @@
    margin-bottom: 2rem;
    background: var(--color-foreground-background);
  }
-
  .commit {
+
  .commit-group-headers {
    cursor: pointer;
  }
-
  .commit:first-child {
+
  .commit-group-headers:first-child {
    border-top-left-radius: 0.25rem;
    border-top-right-radius: 0.25rem;
  }
-
  .commit:last-child {
+
  .commit-group-headers:last-child {
    border-bottom-left-radius: 0.25rem;
    border-bottom-right-radius: 0.25rem;
  }
-
  .commit:hover {
+
  .commit-group-headers {
    background: var(--color-foreground-background-lighter);
  }
  @media (max-width: 960px) {
@@ -61,10 +57,8 @@
          <p>{group.time}</p>
        </header>
        <div class="commit-group-headers">
-
          {#each group.commits as commit (commit.sha1)}
-
            <div class="commit" on:click={() => navigateHistory(commit.sha1, ProjectContent.Commit)}>
-
              <CommitTeaser {commit} on:browseCommit={(event) => navigateHistory(event.detail)} />
-
            </div>
+
          {#each group.commits as commit (commit.header.sha1)}
+
            <CommitTeaser {project} {commit} />
          {/each}
        </div>
      </div>
modified src/commit.ts
@@ -2,9 +2,14 @@ import type { Stats } from "@app/project";
import type { Diff } from "@app/diff";

export interface CommitsHistory {
-
  headers: CommitHeader[];
+
  headers: CommitHeaderWithContext[];
  stats: Stats;
}
+

+
export interface CommitHeaderWithContext {
+
  header: CommitHeader;
+
  context: CommitContext;
+
}
export interface GroupedCommitsHistory {
  headers: CommitGroup[];
  stats: Stats;
@@ -27,6 +32,20 @@ export interface GroupedCommitsHistory {
  stats: Stats;
}

+
export interface Person {
+
  name: string;
+
}
+

+
export interface CommitContext {
+
  committer: {
+
    peer: {
+
      id: string;
+
      person: Person;
+
      delegate: boolean;
+
    };
+
  };
+
}
+

export interface CommitHeader {
  author: Author;
  committer: Author;
@@ -39,7 +58,7 @@ export interface CommitHeader {
// A set of commits grouped by time.
export interface CommitGroup {
  time: string;
-
  commits: CommitHeader[];
+
  commits: CommitHeaderWithContext[];
}

export interface CommitStats {
@@ -69,14 +88,14 @@ export const groupCommitHistory = (
  return { ...history, headers: groupCommits(history.headers) };
};

-
export function groupCommits(commits: CommitHeader[]): CommitGroup[] {
+
export function groupCommits(commits: { header: CommitHeader; context: CommitContext }[]): CommitGroup[] {
  const groupedCommits: CommitGroup[] = [];
  let groupDate: Date | undefined = undefined;

  commits = commits.sort((a, b) => {
-
    if (a.committerTime > b.committerTime) {
+
    if (a.header.committerTime > b.header.committerTime) {
      return -1;
-
    } else if (a.committerTime < b.committerTime) {
+
    } else if (a.header.committerTime < b.header.committerTime) {
      return 1;
    }

@@ -84,7 +103,7 @@ export function groupCommits(commits: CommitHeader[]): CommitGroup[] {
  });

  for (const commit of commits) {
-
    const time = commit.committerTime * 1000;
+
    const time = commit.header.committerTime * 1000;
    const date = new Date(time);
    const isNewDay =
      !groupedCommits.length ||