Add explore seeds to landing page

Signed-off-by: Sebastian Martinez <sebastinez@me.com>
Signed-off-by: Alexis Sellier <self@cloudhead.io>
This commit is contained in:
Sebastian Martinez
2022-02-23 11:40:05 +01:00
committed by Alexis Sellier
parent 8ca59d11a8
commit d69907be45
7 changed files with 97 additions and 15 deletions
+47 -11
View File
@@ -1,18 +1,30 @@
<script lang="ts">
import { onMount } from 'svelte';
import { Link } from 'svelte-routing';
import Avatar from '@app/Avatar.svelte';
import type { Profile } from '@app/profile';
import type { Config } from '@app/config';
import { formatName, formatAddress } from '@app/utils';
import type { Seed } from '@app/base/seeds/Seed';
export let profile: Profile | {
address: string;
avatar?: string;
name?: string;
} ;
} | null = null;
export let seed: Seed | null = null;
export let config: Config;
export let path: string;
export let members: string[] = [];
let numberOfProjects: number | null = null;
onMount(async () => {
if (seed) {
const projects = await seed.getProjects();
numberOfProjects = projects.length;
}
});
</script>
<style>
@@ -55,6 +67,16 @@
color: var(--color-foreground-faded);
}
.card.seed {
width: 14rem;
}
.card.seed .card-label {
max-width: 12rem;
}
.card.seed .seed-emoji {
font-size: 3rem;
}
@media (max-width: 720px) {
.card {
margin-right: 0;
@@ -63,22 +85,36 @@
</style>
<Link to={path}>
<div class="card">
<div class="card" class:seed={!!seed}>
<div class="card-avatar">
<Avatar source={profile.avatar ?? profile.address} address={profile.address} />
{#if profile}
<Avatar source={profile.avatar ?? profile.address} address={profile.address} />
{:else if seed}
<span class="seed-emoji">
{seed.emoji}
</span>
{/if}
</div>
<div class="card-label">
{#if profile.name}
{formatName(profile.name, config)}
{:else}
{formatAddress(profile.address)}
{#if profile}
{#if profile.name}
{formatName(profile.name, config)}
{:else}
{formatAddress(profile.address)}
{/if}
{:else if seed}
{seed.host}
{/if}
</div>
<div class="card-members">
{#if members.length > 0}
{members.length} member(s)
{:else}
{formatAddress(profile.address)}
{#if profile}
{#if members.length > 0}
{members.length} member(s)
{:else}
{formatAddress(profile.address)}
{/if}
{:else if numberOfProjects}
{numberOfProjects} project(s)
{/if}
</div>
</div>
+7 -1
View File
@@ -4,10 +4,12 @@
import Card from '@app/Card.svelte';
import type { Org } from '@app/base/orgs/Org';
import type { Config } from '@app/config';
import type { Seed } from '@app/base/seeds/Seed';
export let config: Config;
export let orgs: Org[] = [];
export let profiles: Profile[] = [];
export let seeds: Seed[] = [];
const orgMembers: Record<string, string[]> = {};
@@ -52,7 +54,11 @@
<Card {profile} {config} path={`/${profile.nameOrAddress}`} />
{/each}
{#if !orgs.length && !profiles.length}
{#each seeds as seed}
<Card {seed} {config} path={`/seeds/${seed.host}`} />
{/each}
{#if !orgs.length && !profiles.length && !seeds.length}
<slot />
{/if}
</div>
+15 -2
View File
@@ -7,6 +7,7 @@
import Message from '@app/Message.svelte';
import Cards from '@app/Cards.svelte';
import { setOpenGraphMetaTag } from '@app/utils';
import { Seed } from '@app/base/seeds/Seed';
export let config: Config;
@@ -24,8 +25,12 @@
? Profile.getMulti(config.users.pinned, config)
: Promise.resolve([]);
const getEntities = Promise.all([getUsers, getOrgs]).then(([users, orgs]) => {
return { users, orgs };
const getSeeds = Object.keys(config.seeds.pinned).length > 0
? Seed.lookupMulti(Object.keys(config.seeds.pinned), config)
: Promise.resolve([]);
const getEntities = Promise.all([getUsers, getOrgs, getSeeds]).then(([users, orgs, seeds]) => {
return { users, orgs, seeds };
});
const viewMore = () => {
@@ -88,6 +93,14 @@
<Loading center />
</div>
{:then entities}
{#if entities.seeds.length}
<div class="heading">
Explore <strong>seed nodes</strong> on the Radicle network.
</div>
<Cards {config} seeds={entities.seeds}>
<div class="empty">There are no seed nodes.</div>
</Cards>
{/if}
{#if entities.orgs.length || entities.users.length}
<div class="heading">
Explore <strong>orgs</strong> and <strong>users</strong> on the Radicle network.
+12
View File
@@ -24,6 +24,7 @@ export class Seed {
link: { host: string; id: string; port: number };
version?: string;
emoji: string;
constructor(seed: {
host: string;
@@ -58,6 +59,13 @@ export class Seed {
assert(isDomain(git), `invalid seed git host ${git}`);
}
const meta = cfg.seeds.pinned[seed.host];
if (meta) {
this.emoji = meta.emoji;
} else {
this.emoji = "🌱";
}
// The `git` and `api` keys being more specific take
// precedence over the `host`, if available.
api = api ?? seed.host;
@@ -117,4 +125,8 @@ export class Seed {
version: info.version,
}, cfg);
}
static async lookupMulti(hostnames: string[], cfg: Config): Promise<Seed[]> {
return await Promise.all(hostnames.map(h => Seed.lookup(h, cfg)));
}
}
+1 -1
View File
@@ -78,7 +78,7 @@
<div class="info">
<span class="title">
<span class="bold">
{host} 🌱
{host} {seed.emoji}
</span>
</span>
</div>
+13
View File
@@ -26,6 +26,19 @@
"cloudhead.radicle.eth"
]
},
"seeds": {
"pinned": {
"willow.radicle.garden": {
"emoji": "🪵"
},
"pine.radicle.garden": {
"emoji": "🌲"
},
"maple.radicle.garden": {
"emoji": "🍁"
}
}
},
"safe": {
"api": "https://safe-transaction.gnosis.io",
"viewer": "https://gnosis-safe.io/app/#/safes"
+2
View File
@@ -32,6 +32,7 @@ export class Config {
reverseRegistrar: { address: string };
orgs: { subgraph: string; contractHash: string; pinned: string[] };
users: { pinned: string[] };
seeds: { pinned: Record<string, { emoji: string }> };
gasLimits: { createOrg: number };
provider: ethers.providers.JsonRpcProvider;
signer: ethers.Signer & TypedDataSigner | WalletConnectSigner | null;
@@ -108,6 +109,7 @@ export class Config {
this.reverseRegistrar = cfg.reverseRegistrar;
this.orgs = cfg.orgs;
this.users = cfg.users;
this.seeds = cfg.seeds;
this.safe = cfg.safe;
this.safe.client = this.safe.api
? new SafeServiceClient(this.safe.api)