Implement more simplifications

Signed-off-by: Alexis Sellier <self@cloudhead.io>
This commit is contained in:
Alexis Sellier
2022-02-12 00:37:00 +01:00
parent 7e9e407382
commit c58db9d278
10 changed files with 109 additions and 144 deletions
+22 -18
View File
@@ -212,29 +212,33 @@ export class Org {
async getPendingProjects(config: Config): Promise<PendingAnchor[]> {
if (! config.safe.client) return [];
const orgAddr = ethers.utils.getAddress(this.address);
const response = await config.safe.client.getPendingTransactions(
ethers.utils.getAddress(this.owner)
);
const projects: PendingAnchor[] = [];
try {
const orgAddr = ethers.utils.getAddress(this.address);
const response = await config.safe.client.getPendingTransactions(
ethers.utils.getAddress(this.owner)
);
const projects: PendingAnchor[] = [];
for (const tx of response.results || []) {
if (tx.data && tx.to === orgAddr) {
const anchor = parseAnchorTx(tx.data, config);
const confirmations = tx.confirmations?.map(t => t.owner) || [];
for (const tx of response.results || []) {
if (tx.data && tx.to === orgAddr) {
const anchor = parseAnchorTx(tx.data, config);
const confirmations = tx.confirmations?.map(t => t.owner) || [];
if (anchor) {
projects.push({
id: anchor.id,
anchor: { stateHash: anchor.stateHash },
confirmations,
safeTxHash: tx.safeTxHash,
confirmed: false,
});
if (anchor) {
projects.push({
id: anchor.id,
anchor: { stateHash: anchor.stateHash },
confirmations,
safeTxHash: tx.safeTxHash,
confirmed: false,
});
}
}
}
return projects;
} catch {
return [];
}
return projects;
}
static async getAnchor(orgAddr: string, urn: string, config: Config): Promise<string | null> {
+1 -1
View File
@@ -1,7 +1,7 @@
<script lang="ts">
import { createEventDispatcher } from "svelte";
import { ProjectInfo, Branches, getOid } from "@app/project";
import { formatCommit, isOid } from "@app/utils";
import { formatCommit } from "@app/utils";
import Dropdown from "@app/Dropdown.svelte";
export let branches: Branches;
+2 -2
View File
@@ -25,7 +25,7 @@
$: browser = $browserStore;
$: path = browser.path || "/";
$: revision = browser.revision || browser.branches[project.head];
$: revision = browser.revision || source.branches[project.head];
// When the component is loaded the first time, the blob is yet to be loaded.
let state: State = { status: Status.Loading, path };
@@ -71,7 +71,7 @@
mobileFileTree = !mobileFileTree;
};
$: commit = proj.getOid(revision, browser.branches) || project.head;
$: commit = proj.getOid(revision, source.branches) || project.head;
$: getBlob = loadBlob(path);
$: loadingPath = state.status == Status.Loading ? state.path : null;
</script>
+1 -8
View File
@@ -14,7 +14,6 @@
export let commit: string;
export let browserStore: Writable<Browser>;
export let peerSelector: boolean; // If peerSelector should be showed.
export let branches: proj.Branches;
let { urn, project, peers, seed, anchors } = source;
@@ -22,12 +21,6 @@
$: revision = browser.revision || commit;
$: content = browser.content;
$: if (Object.keys(browser.branches).length > 0) {
branches = browser.branches;
} else {
proj.browse({ branches });
}
let dropdownState: { [key: string]: boolean } = { clone: false, seed: false, branch: false, peer: false };
function toggleDropdown(input: string) {
Object.keys(dropdownState).map((key: string) => {
@@ -164,7 +157,7 @@
bind:peersDropdown={dropdownState.peer}
on:peerChanged={(event) => updatePeer(event.detail)} />
{/if}
<BranchSelector {branches} {project} {revision} {toggleDropdown}
<BranchSelector branches={source.branches} {project} {revision} {toggleDropdown}
bind:branchesDropdown={dropdownState.branch}
on:branchChanged={(event) => updateRevision(event.detail)} />
<div class="anchor">
+16 -10
View File
@@ -7,12 +7,16 @@
import { browserStore } from '@app/project';
import Header from '@app/base/projects/Header.svelte';
import ProjectContentRoutes from '@app/base/projects/ProjectContentRoutes.svelte';
import Browser from "./Browser.svelte";
import Commit from "./Commit.svelte";
import History from "./History.svelte";
export let peer: string | null = null;
export let config: Config;
export let source: proj.Source;
export let peerSelector = false;
export let content: proj.ProjectContent;
export let revision: string;
const project = source.project;
@@ -43,11 +47,6 @@
{ prop: "og:description", content: project.description },
{ prop: "og:url", content: window.location.href }
]);
// Necessary for the initial load, but causes double rendering.
// Once the content routing is above this component, this can go
// away.
$: revision = $browserStore.revision;
</script>
<style>
@@ -119,9 +118,16 @@
<div class="description">{source.project.description}</div>
</header>
{#await proj.getRoot(source.project, revision, peer, source.seed.api) then { tree, branches, commit }}
<Header {tree} {branches} {commit} {browserStore} {source} {peerSelector} />
<ProjectContentRoutes {tree} {peer} {branches} {browserStore} {source} />
{#await proj.getRoot(source.project, revision, source.branches, source.seed.api) then { tree, commit }}
<Header {tree} {commit} {browserStore} {source} peerSelector={! source.profile} />
{#if content == proj.ProjectContent.Tree}
<Browser {source} {tree} {browserStore} />
{:else if content == proj.ProjectContent.History}
<History {source} {commit} />
{:else if content == proj.ProjectContent.Commit}
<Commit {source} {commit} />
{/if}
{:catch err}
<div class="container center-content">
<div class="error error-message text-xsmall">
+11 -38
View File
@@ -1,65 +1,38 @@
<script lang="ts">
import type { Writable } from "svelte/store";
import { Route, Router } from "svelte-routing";
import type * as proj from "@app/project";
import type { Config } from "@app/config";
import { ProjectContent } from "@app/project";
import Browser from "./Browser.svelte";
import Commit from "./Commit.svelte";
import History from "./History.svelte";
import RouteContext from "./RouteContext.svelte";
export let config: Config;
export let source: proj.Source;
export let tree: proj.Tree;
export let browserStore: Writable<proj.Browser>;
export let peer: string | null;
export let branches: proj.Branches;
const project = source.project;
</script>
<Router>
<!-- The default action is to render Browser with the default branch head -->
<Route path="/">
<RouteContext {browserStore} {peer} {branches} {project}>
<Browser {source} {tree} {browserStore} />
</RouteContext>
<RouteContext content={ProjectContent.Tree} {peer} {source} {config} />
</Route>
<Route path="/tree">
<RouteContext {browserStore} {peer} {branches} {project}>
<Browser {source} {tree} {browserStore} />
</RouteContext>
<RouteContext content={ProjectContent.Tree} {peer} {source} {config} />
</Route>
<Route path="/tree/*" let:params>
<RouteContext route={params["*"]} {browserStore} {peer} {branches} {project}>
<Browser {source} {tree} {browserStore} />
</RouteContext>
<RouteContext route={params["*"]} content={ProjectContent.Tree} {peer} {source} {config} />
</Route>
<Route path="/history">
<RouteContext {browserStore} content={ProjectContent.History} {peer} {branches} {project} let:commit>
{#if commit}
<History {source} {commit} />
{/if}
</RouteContext>
<RouteContext content={ProjectContent.History} {peer} {source} {config} />
</Route>
<Route path="/history/*" let:params>
<RouteContext route={params["*"]} {browserStore} content={ProjectContent.History} {peer} {branches} {project} let:commit>
{#if commit}
<History {source} {commit} />
{/if}
</RouteContext>
<RouteContext route={params["*"]} content={ProjectContent.History} {peer} {source} {config} />
</Route>
<Route path="/commits/:commit" let:params>
<RouteContext revision={params.commit} {browserStore} {project} content={ProjectContent.Commit} {peer} {branches} let:revision>
{#if revision}
<Commit {source} commit={revision} />
{/if}
</RouteContext>
<RouteContext revision={params.commit} content={ProjectContent.Commit} {peer} {source} {config} />
</Route>
<Route path="/commits/*" let:params>
<RouteContext route={params["*"]} {browserStore} {project} content={ProjectContent.Commit} {peer} {branches} let:revision>
{#if revision}
<Commit {source} commit={revision} />
{/if}
</RouteContext>
<RouteContext route={params["*"]} content={ProjectContent.Commit} {peer} {source} {config} />
</Route>
</Router>
+18 -20
View File
@@ -1,42 +1,40 @@
<script lang="ts">
import type { Writable } from 'svelte/store';
import type { Config } from "@app/config";
import * as proj from '@app/project';
export let browserStore: Writable<proj.Browser>;
import Project from './Project.svelte';
export let browserStore: Writable<proj.Browser> = proj.browserStore;
export let route: string | null = null;
export let revision: string | null = null;
export let peer: string | null;
export let content: proj.ProjectContent = proj.ProjectContent.Tree;
export let branches: proj.Branches;
export let project: proj.ProjectInfo;
export let source: proj.Source;
export let config: Config;
const browse: any = { content, peer, branches, path: "/" };
const browse: any = { content, peer, path: "/" };
const head = source.branches[source.project.defaultBranch];
$: if (route) {
const result = proj.splitPrefixFromPath(route, $browserStore.branches);
const { path, revision } = proj.parseRoute(route, source.branches);
console.log("RouteParser", route, result);
if (result) {
const [revision, path] = result;
browse.revision = revision;
browse.path = path;
}
if (path) browse.path = path;
if (revision) browse.revision = revision;
} else if (revision) {
browse.revision = revision;
} else {
browse.revision = branches[project.defaultBranch];
browse.revision = head;
}
$: proj.browse(browse);
$: browser = $browserStore;
$: commit = browser.revision && proj.getOid(browser.revision, browser.branches);
</script>
<slot
revision={browser.revision}
<Project
peer={browser.peer}
path={browser.path || "/"}
{commit}
></slot>
revision={browser.revision || head}
content={browser.content}
{source}
{config}
/>
-1
View File
@@ -5,7 +5,6 @@
import Redirect from "@app/Redirect.svelte";
export let config: Config;
</script>
<!-- With an Seed context -->
+14 -15
View File
@@ -7,7 +7,7 @@
import { Seed } from '@app/base/seeds/Seed';
import NotFound from '@app/NotFound.svelte';
import Project from './Project.svelte';
import ProjectContentRoutes from './ProjectContentRoutes.svelte';
export let id: string; // Project name or URN.
export let seedHost: string | null = null;
@@ -15,14 +15,6 @@
export let peer: string | null = null;
export let config: Config;
// Show peer selector only if we're browsing via a seed.
const peerSelector = Boolean(seedHost);
// Nb. Once we move the content routing above this component, this should
// no longer be necessary, but right now, we have the project header that
// is rendered before the routes are parsed, so we have to set this here.
proj.browse({ peer });
const getProject = async (): Promise<proj.Source> => {
const profile = profileName ? await Profile.get(profileName, ProfileType.Project, config) : null;
const seed = profile ? profile.seed : seedHost ? await Seed.lookup(seedHost, config) : null;
@@ -34,18 +26,25 @@
throw new Error("Couldn't load project: invalid seed");
}
const info = await proj.getInfo(id, seed.api);
const urn = isRadicleId(id) ? id : info.urn;
const project = await proj.getInfo(id, seed.api);
const urn = isRadicleId(id) ? id : project.urn;
const anchors = profile ? await profile.confirmedProjectAnchors(urn, config) : [];
// Older versions of http-api don't include the URN.
if (! info.urn) info.urn = urn;
if (! project.urn) project.urn = urn;
const peers: proj.PeerId[] = info.delegates
const peers: proj.PeerId[] = project.delegates
? await proj.getRemotes(urn, seed.api)
: [];
return { urn, seed, project: info, peers, profile, anchors };
let remote: proj.Remote = {
heads: { [project.defaultBranch]: project.head }
};
if (peer) {
remote = await proj.getRemote(urn, peer, seed.api);
}
return { urn, seed, project, peers, branches: remote.heads, profile, anchors };
};
</script>
@@ -77,7 +76,7 @@
<Loading center />
</header>
{:then source}
<Project {source} {peer} {config} {peerSelector} />
<ProjectContentRoutes {source} {peer} {config} />
{:catch}
<NotFound title={id} subtitle="This project was not found." />
{/await}
+24 -31
View File
@@ -33,6 +33,7 @@ export interface Source {
urn: string;
project: ProjectInfo;
peers: PeerId[];
branches: Branches;
anchors: string[];
seed: Seed;
profile?: Profile | null;
@@ -97,7 +98,6 @@ export interface Remote {
export interface Browser {
content: ProjectContent;
branches: Branches;
revision: string | null;
peer: string | null;
path: string | null;
@@ -112,21 +112,16 @@ export const browserStore = writable({
} as Browser);
export interface BrowseTo {
content?: ProjectContent;
revision?: string | null;
path?: string | null;
peer?: string | null;
branches?: Branches;
}
export interface PathOptions {
urn: string;
content?: ProjectContent;
profile?: string | null;
seed?: string | null;
peer?: string | null;
revision?: string | null;
path?: string | null;
peer?: string | null;
}
export interface PathOptions extends BrowseTo {
urn: string;
profile?: string | null;
seed?: string | null;
}
export function browse(browse: BrowseTo): void {
@@ -191,28 +186,20 @@ export async function getRemotes(urn: string, host: api.Host): Promise<PeerId[]>
export async function getRoot(
project: ProjectInfo,
revision: string | null,
peer: string | null,
heads: Branches,
host: api.Host
): Promise<{ tree: Tree; branches: Branches; commit: string }> {
): Promise<{ tree: Tree; commit: string }> {
const urn = project.urn;
let remote: Remote = {
heads: { [project.defaultBranch]: project.head }
};
if (peer) {
remote = await getRemote(urn, peer, host);
}
const head = remote.heads[project.defaultBranch];
const commit = revision ? getOid(revision, remote.heads) : head;
const head = heads[project.defaultBranch];
const commit = revision ? getOid(revision, heads) : head;
if (! commit) {
throw new Error(`Revision ${revision} not found`);
}
const tree = await getTree(urn, commit, "/", host);
return { tree, branches: remote.heads, commit };
return { tree, commit };
}
export async function getTree(
@@ -298,16 +285,22 @@ export function getOid(revision: string, branches?: Branches): string | null {
return null;
}
// Splits the path consisting of a revision (eg. branch or commit) and file path into a tuple [revision, file-path]
export function splitPrefixFromPath(input: string, branches: Branches): [string, string] | null {
// Parses the path consisting of a revision (eg. branch or commit) and file path into a tuple [revision, file-path]
export function parseRoute(input: string, branches: Branches): { path?: string; revision?: string } {
const branch = Object.entries(branches).find(([branchName,]) => input.startsWith(branchName));
const commitPath = [input.slice(0, 40), input.slice(41)];
const parsed: { path?: string; revision?: string } = {};
if (branch) {
const [rev, path] = [input.slice(0, branch[0].length), input.slice(branch[0].length + 1)];
return [rev, path ? path : "/"];
parsed.revision = rev;
parsed.path = path ? path : "/";
} else if (isOid(commitPath[0])) {
return [commitPath[0], commitPath[1] ? commitPath[1] : "/"];
parsed.revision = commitPath[0];
parsed.path = commitPath[1] ? commitPath[1] : "/";
} else {
parsed.path = input;
}
return null;
return parsed;
}