Improve loading of Cars component

Signed-off-by: Sebastian Martinez <sebastinez@me.com>
This commit is contained in:
Sebastian Martinez
2021-11-22 10:45:44 +01:00
parent c1e67bf776
commit 8b8b29d666
7 changed files with 46 additions and 42 deletions
+5 -1
View File
@@ -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[] = [];
+15 -23
View File
@@ -1,23 +1,20 @@
<script lang="ts">
import { ethers } from 'ethers';
import { onMount } from '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 { Profile, ProfileType } from '@app/profile';
import Card from '@app/Card.svelte';
import type { Org } from '@app/base/orgs/Org';
import type { Config } from '@app/config';
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}
+4 -2
View File
@@ -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();
+1 -1
View File
@@ -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 = () => {
+5 -5
View File
@@ -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);
+14 -10
View File
@@ -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); });
}
+2
View File
@@ -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 {