mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-10-18 19:30:27 +08:00
Show project with anchor when no commit hash passed
Signed-off-by: Sebastian Martinez <sebastinez@me.com>
This commit is contained in:
@@ -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<string[]> {
|
||||
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)));
|
||||
}
|
||||
@@ -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<string[] | null> {
|
||||
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);
|
||||
</script>
|
||||
|
||||
@@ -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 @@
|
||||
<BranchSelector {branches} {project} {revision} {toggleDropdown}
|
||||
bind:branchesDropdown={dropdownState.branch}
|
||||
on:revisionChanged={(event) => updateRevision(event.detail)} />
|
||||
{#if anchors}
|
||||
<div class="anchor">
|
||||
{#await getAnchor}
|
||||
<Loading small margins />
|
||||
{:then anchor}
|
||||
{#if anchor}
|
||||
<!-- commit is head and latest anchor -->
|
||||
{#if commit == anchor[0] && commit === project.head}
|
||||
<span class="anchor-widget anchor-latest">
|
||||
<span class="anchor-label" title="{anchors}">latest 🔐</span>
|
||||
</span>
|
||||
<!-- commit is not head but latest anchor -->
|
||||
{:else if commit == anchor[0] && commit !== project.head}
|
||||
<span class="anchor-widget" on:click={() => updateRevision(project.head)}>
|
||||
<span class="anchor-label" title="{anchors}">latest 🔐</span>
|
||||
</span>
|
||||
<!-- commit is not head a stale anchor -->
|
||||
{:else if anchor?.includes(commit)}
|
||||
<span class="anchor-widget" on:click={() => updateRevision(anchor[0])}>
|
||||
<span class="anchor-label" title="{anchors}">stale 🔒</span>
|
||||
</span>
|
||||
<!-- commit is not anchored, could be head or any other commit -->
|
||||
{:else}
|
||||
<span class="anchor-widget not-anchored" on:click={() => updateRevision(anchor[0])}>
|
||||
<span class="anchor-label">not anchored 🔓</span>
|
||||
</span>
|
||||
{/if}
|
||||
{:else}
|
||||
<!-- commit is not head and neither an anchor, and there are no anchors available -->
|
||||
<span class="anchor-widget not-anchored not-allowed">
|
||||
<span class="anchor-label">not anchored 🔓</span>
|
||||
</span>
|
||||
{/if}
|
||||
{:catch}
|
||||
<span class="anchor-widget error" title="Not able to fetch anchor from subgraph">
|
||||
<span class="anchor-label">❌</span>
|
||||
<div class="anchor">
|
||||
{#if anchors}
|
||||
<!-- commit is head and latest anchor -->
|
||||
{#if commit == anchors[0] && commit === project.head}
|
||||
<span class="anchor-widget anchor-latest">
|
||||
<span class="anchor-label" title="{anchors[0]}">latest 🔐</span>
|
||||
</span>
|
||||
{/await}
|
||||
</div>
|
||||
{/if}
|
||||
<!-- commit is not head but latest anchor -->
|
||||
{:else if commit == anchors[0] && commit !== project.head}
|
||||
<span class="anchor-widget" on:click={() => updateRevision(project.head)}>
|
||||
<span class="anchor-label" title="{anchors[0]}">latest 🔐</span>
|
||||
</span>
|
||||
<!-- commit is not head a stale anchor -->
|
||||
{:else if anchors.includes(commit)}
|
||||
<span class="anchor-widget" on:click={() => updateRevision(anchors[0])}>
|
||||
<span class="anchor-label" title="{commit}">stale 🔒</span>
|
||||
</span>
|
||||
<!-- commit is not anchored, could be head or any other commit -->
|
||||
{:else}
|
||||
<span class="anchor-widget not-anchored" on:click={() => updateRevision(anchors[0])}>
|
||||
<span class="anchor-label">not anchored 🔓</span>
|
||||
</span>
|
||||
{/if}
|
||||
{:else}
|
||||
<!-- commit is not head and neither an anchor, and there are no anchors available -->
|
||||
<span class="anchor-widget not-anchored not-allowed">
|
||||
<span class="anchor-label">not anchored 🔓</span>
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
{#if config.seed.git.host}
|
||||
<span>
|
||||
<div class="clone" on:click={() => toggleDropdown("clone")}>
|
||||
|
||||
@@ -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;
|
||||
</script>
|
||||
|
||||
<Router>
|
||||
<!-- The default action is to render Browser with the default branch head -->
|
||||
<Route path="/">
|
||||
<Browser {urn} {org} {user} {seed} {config} {tree} {project} {branches} {peer}
|
||||
locator={project.head}
|
||||
<Browser {urn} {org} {user} {seed} {config} {tree} {project} {branches} {peer} {locator}
|
||||
bind:content={content}
|
||||
bind:path={path}
|
||||
bind:revision={revision} />
|
||||
</Route>
|
||||
<Route path="/tree">
|
||||
<Browser {urn} {org} {user} {seed} {config} {tree} {project} {branches} {peer}
|
||||
locator={project.head}
|
||||
<Browser {urn} {org} {user} {seed} {config} {tree} {project} {branches} {peer} {locator}
|
||||
bind:content={content}
|
||||
bind:path={path}
|
||||
bind:revision={revision} />
|
||||
@@ -43,7 +44,7 @@
|
||||
bind:revision={revision} />
|
||||
</Route>
|
||||
<Route path="/history">
|
||||
<History {urn} locator={project.head} {config} {project} {branches}
|
||||
<History {urn} {config} {project} {branches} {locator}
|
||||
bind:content={content}
|
||||
bind:revision={revision} />
|
||||
</Route>
|
||||
|
||||
@@ -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 @@
|
||||
</header>
|
||||
{#await proj.getTree(urn, getOid(result.project.head, revision, result.branches), "/", config) then tree}
|
||||
<Header {urn} {tree} {revision} {content} {path} {peer}
|
||||
anchors={result.profile?.anchorsAccount ?? org}
|
||||
anchors={result.anchors}
|
||||
peerSelector={!!seed}
|
||||
config={result.config}
|
||||
project={result.project}
|
||||
@@ -187,6 +189,7 @@
|
||||
on:routeParamsChange={updateRouteParams} />
|
||||
<ProjectContentRoutes {urn} {org} {user} {seed} {tree} {peer}
|
||||
project={result.project}
|
||||
anchors={result.anchors}
|
||||
branches={result.branches}
|
||||
config={result.config}
|
||||
bind:content={content}
|
||||
|
||||
Reference in New Issue
Block a user