diff --git a/src/anchors.ts b/src/anchors.ts new file mode 100644 index 000000000..f7e30e3d9 --- /dev/null +++ b/src/anchors.ts @@ -0,0 +1,28 @@ +import { ethers } from "ethers"; +import type { Config } from "./config"; +import { decodeRadicleId, formatProjectHash, querySubgraph } from "./utils"; + +const GetAllAnchors = ` + query GetAllAnchors($project: Bytes!, $org: ID!) { + anchors(orderBy: timestamp, orderDirection: desc, where: { objectId: $project, org: $org }) { + multihash + timestamp + } + } +`; + +interface AnchorObject { + timestamp: number; + multihash: string; +} + +export async function getAllAnchors(config: Config, urn: string, anchors?: string | null): Promise { + if (! anchors) { + return []; + } + const unpadded = decodeRadicleId(urn); + const id = ethers.utils.hexZeroPad(unpadded, 32); + const allAnchors = await querySubgraph(config.orgs.subgraph, GetAllAnchors, { project: id, org: anchors }); + return allAnchors.anchors + .map((anchor: AnchorObject) => formatProjectHash(ethers.utils.arrayify(anchor.multihash))); +} diff --git a/src/base/projects/Header.svelte b/src/base/projects/Header.svelte index 6eca5e94e..8ebdcbdeb 100644 --- a/src/base/projects/Header.svelte +++ b/src/base/projects/Header.svelte @@ -2,8 +2,6 @@ import { navigate } from 'svelte-routing'; import type { Config } from '@app/config'; import * as utils from '@app/utils'; - import Loading from '@app/Loading.svelte'; - import { ethers } from "ethers"; import { ProjectContent, getOid } from '@app/project'; import type { Info, Tree } from "@app/project"; import BranchSelector from './BranchSelector.svelte'; @@ -13,7 +11,7 @@ const dispatch = createEventDispatcher(); export let config: Config; - export let anchors: string | null = null; + export let anchors: string[]; export let urn: string; export let path: string; export let project: Info; @@ -49,32 +47,6 @@ dispatch("routeParamsChange", { content, revision: newRevision, peer, path }); }; - const GetAllAnchors = ` - query GetAllAnchors($project: Bytes!, $org: ID!) { - anchors(orderBy: timestamp, orderDirection: desc, where: { objectId: $project, org: $org }) { - multihash - timestamp - } - } - `; - - interface AnchorObject { - timestamp: number; - multihash: string; - } - - async function getAllAnchors(anchors: string | null, urn: string): Promise { - if (! anchors) { - return null; - } - const unpadded = utils.decodeRadicleId(urn); - const id = ethers.utils.hexZeroPad(unpadded, 32); - const allAnchors = await utils.querySubgraph(config.orgs.subgraph, GetAllAnchors, { project: id, org: anchors }); - return allAnchors.anchors - .map((anchor: AnchorObject) => utils.formatProjectHash(ethers.utils.arrayify(anchor.multihash))); - } - - $: getAnchor = anchors ? getAllAnchors(anchors, urn) : null; $: commit = getOid(project.head, revision, branches); @@ -192,10 +164,6 @@ background: var(--color-foreground-90); } - .error { - color: var(--color-negative); - cursor: not-allowed; - } @media (max-width: 960px) { header { padding-left: 2rem; @@ -221,46 +189,36 @@ updateRevision(event.detail)} /> - {#if anchors} -
- {#await getAnchor} - - {:then anchor} - {#if anchor} - - {#if commit == anchor[0] && commit === project.head} - - latest 🔐 - - - {:else if commit == anchor[0] && commit !== project.head} - updateRevision(project.head)}> - latest 🔐 - - - {:else if anchor?.includes(commit)} - updateRevision(anchor[0])}> - stale 🔒 - - - {:else} - updateRevision(anchor[0])}> - not anchored 🔓 - - {/if} - {:else} - - - not anchored 🔓 - - {/if} - {:catch} - - ❌ +
+ {#if anchors} + + {#if commit == anchors[0] && commit === project.head} + + latest 🔐 - {/await} -
- {/if} + + {:else if commit == anchors[0] && commit !== project.head} + updateRevision(project.head)}> + latest 🔐 + + + {:else if anchors.includes(commit)} + updateRevision(anchors[0])}> + stale 🔒 + + + {:else} + updateRevision(anchors[0])}> + not anchored 🔓 + + {/if} + {:else} + + + not anchored 🔓 + + {/if} +
{#if config.seed.git.host}
toggleDropdown("clone")}> diff --git a/src/base/projects/ProjectContentRoutes.svelte b/src/base/projects/ProjectContentRoutes.svelte index cc2aa611a..e28eec0cf 100644 --- a/src/base/projects/ProjectContentRoutes.svelte +++ b/src/base/projects/ProjectContentRoutes.svelte @@ -15,22 +15,23 @@ export let peer: Peer; export let branches: [string, string][]; export let content: ProjectContent; + export let anchors: string[]; export let revision: string; export let path: string; + + let locator = anchors[0] || project.head; - - @@ -43,7 +44,7 @@ bind:revision={revision} /> - diff --git a/src/base/projects/View.svelte b/src/base/projects/View.svelte index 9ba3ad964..1b35d1c12 100644 --- a/src/base/projects/View.svelte +++ b/src/base/projects/View.svelte @@ -10,6 +10,7 @@ import { formatOrg, formatSeedId } from '@app/utils'; import { getOid } from '@app/project'; import { Seed } from '@app/base/seeds/Seed'; + import { getAllAnchors } from '@app/anchors'; import Header from '@app/base/projects/Header.svelte'; import ProjectContentRoutes from '@app/base/projects/ProjectContentRoutes.svelte'; @@ -43,6 +44,7 @@ const cfg = seed ? config.withSeed(seed) : config; const info = await proj.getInfo(urn, cfg); projectInfo = info; + const anchors = await getAllAnchors(config, urn, profile?.anchorsAccount ?? org); let branches = Array([info.meta.defaultBranch, info.head]) as [string, string][]; let peers: proj.Peer[] = []; @@ -55,7 +57,7 @@ } peers = await proj.getPeers(urn, cfg); } - return { project: info, branches, peers, config: cfg, profile }; + return { project: info, branches, peers, anchors, config: cfg, profile }; }); const parentUrl = (profile: Profile) => { @@ -178,7 +180,7 @@ {#await proj.getTree(urn, getOid(result.project.head, revision, result.branches), "/", config) then tree}