Radish alpha
r
Radicle web interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
Add explore seeds to landing page
Sebastian Martinez committed 4 years ago
commit d69907be4534b5440077118af938bf51f7c7caf4
parent 8ca59d11a8e38c8e412f183fb8a2d702c46d4262
7 files changed +97 -15
modified src/Card.svelte
@@ -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>
modified src/Cards.svelte
@@ -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>
modified src/base/home/Index.svelte
@@ -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.
modified src/base/seeds/Seed.ts
@@ -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)));
+
  }
}
modified src/base/seeds/View.svelte
@@ -78,7 +78,7 @@
      <div class="info">
        <span class="title">
          <span class="bold">
-
            {host} 🌱
+
            {host} {seed.emoji}
          </span>
        </span>
      </div>
modified src/config.json
@@ -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"
modified src/config.ts
@@ -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)