mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-11-16 03:40:37 +08:00
Improve loading of Cars component
Signed-off-by: Sebastian Martinez <sebastinez@me.com>
This commit is contained in:
+5
-1
@@ -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
@@ -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}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 = () => {
|
||||
|
||||
@@ -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
@@ -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); });
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user