Radish alpha
r
Radicle web interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
Improve loading of Cars component
Sebastian Martinez committed 4 years ago
commit 8b8b29d666d13d57e9bf287191ec156145b9fd0b
parent c1e67bf776b9c25f88f8a530f0c6e054db18fd4c
7 files changed +45 -41
modified src/Card.svelte
@@ -5,7 +5,11 @@
  import type { Config } from '@app/config';
  import { formatName, formatAddress } from '@app/utils';

-
  export let profile: Profile;
+
  export let profile: Profile | {
+
    address: string;
+
    avatar?: string;
+
    name?: string;
+
  } ;
  export let config: Config;
  export let path: string;
  export let members: string[] = [];
modified src/Cards.svelte
@@ -1,23 +1,20 @@
<script lang="ts">
-
  import { ethers } from 'ethers';
  import { onMount } from 'svelte';
+
  import { Profile, ProfileType } from '@app/profile';
+
  import Card from '@app/Card.svelte';
  import type { Org } from '@app/base/orgs/Org';
-
  import { Profile } from '@app/profile';
  import type { Config } from '@app/config';
-
  import Loading from '@app/Loading.svelte';
-
  import Card from '@app/Card.svelte';

  export let config: Config;
  export let orgs: Org[] = [];
  export let profiles: Profile[] = [];

  const orgMembers: Record<string, string[]> = {};
-
  const getOrgProfiles = Profile.getMulti(orgs.map(o => o.name ?? o.address), config);

  onMount(async () => {
    const promises = orgs.map(org => {
      org.getMembers(config).then(members => {
-
        orgMembers[ethers.utils.getAddress(org.address)] = members;
+
        orgMembers[org.address] = members;
      });
    });

@@ -31,31 +28,26 @@
    flex-direction: row;
    flex-wrap: wrap;
  }
-
  .loading {
-
    padding: 3rem 0;
-
  }
</style>

-
{#await getOrgProfiles}
-
  <div class="loading">
-
    <Loading center />
-
  </div>
-
{:then orgProfiles}
  <div class="list">
-
    {#each orgProfiles as profile}
-
      {#if orgMembers[profile.address]?.length}
-
        <Card {profile} {config} path={`/orgs/${profile.nameOrAddress}`} members={orgMembers[profile.address]} />
-
      {:else}
-
        <Card {profile} {config} path={`/orgs/${profile.nameOrAddress}`} />
-
      {/if}
+
    {#each orgs as org}
+
      {#await Profile.get(org.name ?? org.address, ProfileType.Minimal, config)}
+
        <Card profile={{ address: org.address }} {config} path={`/orgs/${org.address}`} />
+
      {:then profile}
+
        {#if orgMembers[profile.address]?.length}
+
          <Card {profile} {config} path={`/orgs/${profile.nameOrAddress}`} members={orgMembers[profile.address]} />
+
        {:else}
+
          <Card {profile} {config} path={`/orgs/${profile.nameOrAddress}`} />
+
        {/if}
+
      {/await}
    {/each}

    {#each profiles as profile}
      <Card {profile} {config} path={`/users/${profile.nameOrAddress}`} />
    {/each}

-
    {#if !orgProfiles.length && !profiles.length}
+
    {#if !orgs.length && !profiles.length}
      <slot />
    {/if}
  </div>
-
{/await}
modified src/WalletConnectSigner.ts
@@ -33,8 +33,10 @@ export class WalletConnectSigner extends ethers.Signer {

  async _signTypedData(domain: TypedDataDomain, types: Record<string, Array<TypedDataField>>, value: Record<string, any>): Promise<string> {
    // Populate any ENS names (in-place)
-
    const populated = await _TypedDataEncoder.resolveNames(domain, types, value, (name: string) => {
-
      return this.provider.resolveName(name);
+
    const populated = await _TypedDataEncoder.resolveNames(domain, types, value, async (name: string) => {
+
      const address = await this.provider.resolveName(name);
+
      if (address === null) throw Error("resolver or addr is not configured for ENS name");
+
      return address;
    });

    const address = await this.getAddress();
modified src/base/home/Index.svelte
@@ -18,7 +18,7 @@
    : Promise.resolve([]);

  const getEntities = Promise.all([getUsers, getOrgs]).then(([users, orgs]) => {
-
    return { users: users, orgs: orgs };
+
    return { users, orgs };
  });

  const viewMore = () => {
modified src/base/registrations/registrar.ts
@@ -58,7 +58,7 @@ state.subscribe((s: Connection) => {
  console.log("register.state", s);
});

-
export async function getRegistration(name: string, config: Config, resolver?: EnsResolver): Promise<Registration | null> {
+
export async function getRegistration(name: string, config: Config, resolver?: EnsResolver | null): Promise<Registration | null> {
  name = name.toLowerCase();

  if (! resolver) {
@@ -99,7 +99,7 @@ export async function getRegistration(name: string, config: Config, resolver?: E
  };
}

-
export async function getAvatar(name: string, config: Config, resolver?: EnsResolver): Promise<string | null> {
+
export async function getAvatar(name: string, config: Config, resolver?: EnsResolver | null): Promise<string | null> {
  name = name.toLowerCase();

  resolver = resolver ?? await config.provider.getResolver(name);
@@ -109,7 +109,7 @@ export async function getAvatar(name: string, config: Config, resolver?: EnsReso
  return resolver.getText('avatar');
}

-
export async function getSeedHost(name: string, config: Config, resolver?: EnsResolver): Promise<string | null> {
+
export async function getSeedHost(name: string, config: Config, resolver?: EnsResolver | null): Promise<string | null> {
  name = name.toLowerCase();

  resolver = resolver ?? await config.provider.getResolver(name);
@@ -119,7 +119,7 @@ export async function getSeedHost(name: string, config: Config, resolver?: EnsRe
  return resolver.getText('eth.radicle.seed.host');
}

-
export async function getSeedId(name: string, config: Config, resolver?: EnsResolver): Promise<string | null> {
+
export async function getSeedId(name: string, config: Config, resolver?: EnsResolver | null): Promise<string | null> {
  name = name.toLowerCase();

  resolver = resolver ?? await config.provider.getResolver(name);
@@ -129,7 +129,7 @@ export async function getSeedId(name: string, config: Config, resolver?: EnsReso
  return resolver.getText('eth.radicle.seed.id');
}

-
export async function getAnchorsAccount(name: string, config: Config, resolver?: EnsResolver): Promise<string | null> {
+
export async function getAnchorsAccount(name: string, config: Config, resolver?: EnsResolver | null): Promise<string | null> {
  name = name.toLowerCase();

  resolver = resolver ?? await config.provider.getResolver(name);
modified src/profile.ts
@@ -7,8 +7,8 @@ import type { Config } from "@app/config";

export interface IProfile {
  address: string;
-
  ens: EnsProfile | null;
-
  idx: BasicProfile | null;
+
  ens?: EnsProfile;
+
  idx?: BasicProfile;
}

export enum ProfileType {
@@ -30,12 +30,12 @@ export class Profile {
  }

  // Get the ENS profile
-
  get ens(): EnsProfile | null {
+
  get ens(): EnsProfile | undefined {
    return this.profile.ens;
  }

  // Get the IDX profle
-
  get idx(): BasicProfile | null {
+
  get idx(): BasicProfile | undefined {
    return this.profile.idx;
  }

@@ -125,6 +125,7 @@ export class Profile {
  }

  // Keeping this function private since the desired entrypoint is .get()
+
  // All addresses returned from this function should be lowercase.
  private static async lookupProfile(
    addressOrName: string,
    profileType: ProfileType,
@@ -134,31 +135,34 @@ export class Profile {

    if (ens) {
      if (ens.address) {
-
        return { address: ens.address, ens, idx: null };
+
        return {
+
          address: ens.address.toLowerCase(),
+
          ens: { ...ens, address: ens.address.toLowerCase() }
+
        };
      }
      throw new Error(`No address set for ${addressOrName}`);

    } else if (isAddress(addressOrName)) {
-
      const address = addressOrName;
+
      const address = addressOrName.toLowerCase();

      try {
        const idx = await resolveIdxProfile(
          formatCAIP10Address(address, "eip155", config.network.chainId), config
        );
-
        return { address, ens: null, idx };
+
        return { address, idx: idx ?? undefined };
      } catch (e) {
        // Look for the No DID found for error by the resolveIdxProfile fn and send it to console.debug
        if (e.message.match("No DID found for")) console.debug(e);
        else console.error(e);

-
        return { address, ens: null, idx: null };
+
        return { address };
      }
    }
    throw new Error(`Name ${addressOrName} was not found`);
  }

-
  static async getMulti(addresses: string[], config: Config): Promise<Profile[]> {
-
    const profilePromises = addresses.map(address => this.lookupProfile(address, ProfileType.Minimal, config));
+
  static async getMulti(addressesOrNames: string[], config: Config): Promise<Profile[]> {
+
    const profilePromises = addressesOrNames.map(addressOrName => this.lookupProfile(addressOrName, ProfileType.Minimal, config));
    const profiles = await Promise.all(profilePromises);
    return profiles.map(profile => { return new Profile(profile); });
  }
modified src/utils.ts
@@ -89,6 +89,7 @@ export function formatCAIP10Address(address: string, protocol: string, impl: num
  return `${address.toLowerCase()}@${protocol}:${impl.toString()}`;
}

+
// Returns a checksummed, shortened, without 0x prefix Ethereum address
export function formatAddress(input: string): string {
  const addr = ethers.utils.getAddress(input).replace(/^0x/, "");

@@ -326,6 +327,7 @@ export async function resolveEnsProfile(addressOrName: string, profileType: Prof

      const project = await Promise.allSettled(promises);
      const [avatar, address, seedHost, seedId, anchorsAccount] =
+
        // Just checking for r.value equal null and casting to undefined, since resolver functions return null
        project.map(r => r.status == "fulfilled" ? r.value : null);

      return {