Radish alpha
r
Radicle web interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
Merge pull request #20 from sebastinez/sebastinez/user-identity
Alexis Sellier committed 4 years ago
commit 3190b2617abe790a051e43f5dec39eab9adbc82a
parent e9775ee71563d41ba78e0ce6d1565226184f8195
5 files changed +169 -27
modified src/Address.svelte
@@ -2,16 +2,18 @@
  import { onMount } from 'svelte';
  import { link } from 'svelte-routing';
  import { ethers } from 'ethers';
-
  import { explorerLink, safeLink } from '@app/utils';
-
  import Blockies from '@app/Blockies.svelte';
+
  import { safeLink, identifyAddress, formatAddress, AddressType } from '@app/utils';
  import Loading from '@app/Loading.svelte';
+
  import Avatar from "@app/Avatar.svelte";
  import type { Config } from '@app/config';
-
  import { identifyAddress, formatAddress, AddressType } from '@app/utils';
+
  import type { Registration } from '@app/base/registrations/registrar';
+
  import { getRegistration } from '@app/base/registrations/registrar';

  export let address: string;
  export let config: Config;
  export let resolve = false;
  export let noBadge = false;
+
  export let noAvatar = false;
  export let compact = false;

  let checksumAddress = compact
@@ -19,33 +21,27 @@
    : ethers.utils.getAddress(address);
  let addressType: AddressType | null = null;
  let addressName: string | null = null;
+
  let info: Registration | null;

-
  onMount(() => {
-
    identifyAddress(address, config).then(typ => addressType = typ);
+
  onMount(async () => {
+
    identifyAddress(address, config).then((t: AddressType) => addressType = t);
    if (resolve) {
-
      config.provider.lookupAddress(address).then(name => addressName = name);
+
      addressName = await config.provider.lookupAddress(address);
+
      info = await getRegistration(addressName, config);
    }
  });
-

-
  $: addressLabel = addressName || checksumAddress;
+
  $: addressLabel = addressName ?? checksumAddress;
</script>

<style>
  .address {
    display: flex;
    align-items: center;
+
    height: 100%;
  }
  .address.no-badge .badge {
    display: none;
  }
-
  .icon {
-
    display: inline-block;
-
    width: 1rem;
-
    height: 1rem;
-
    margin-right: 0.5rem;
-
    min-width: 1rem;
-
    min-height: 1rem;
-
  }
  .address a {
    color: var(--color-foreground-90);
  }
@@ -58,22 +54,22 @@
  }
</style>

-
<div class="address" class:no-badge={noBadge}>
-
  <span class="icon"><Blockies address={address} /></span>
+
<div class="address" title={address} class:no-badge={noBadge}>
+
  {#if !noAvatar}
+
    <Avatar inline source={info?.avatar ?? address} />
+
  {/if}
  {#if addressType === AddressType.Org}
    <a use:link href={`/orgs/${address}`}>{addressLabel}</a>
    <span class="badge">org</span>
  {:else if addressType === AddressType.Safe}
    <a href={safeLink(address, config)} target="_blank">{addressLabel}</a>
    <span class="badge safe">safe</span>
-
  {:else}
-
    <a href={explorerLink(address, config)} target="_blank">{addressLabel}</a>
-
    {#if addressType === AddressType.Contract}
-
      <span class="badge">contract</span>
-
    {:else if addressType === AddressType.EOA}
-
      <!-- Don't show anything for EOAs -->
-
    {:else if !noBadge}
-
      <div class="loading"><Loading small /></div>
-
    {/if}
+
  {:else if addressType === AddressType.Contract}
+
    <a href={`/orgs/${address}`} target="_blank">{addressLabel}</a>
+
    <span class="badge">contract</span>
+
  {:else if addressType === AddressType.EOA}
+
    <a href={`/users/${address}`} target="_blank">{addressLabel}</a>
+
  {:else if !noBadge}
+
    <div class="loading"><Loading small /></div>
  {/if}
</div>
modified src/App.svelte
@@ -7,6 +7,7 @@
  import Vesting from '@app/base/vesting/Index.svelte';
  import Registrations from '@app/base/registrations/Routes.svelte';
  import Orgs from '@app/base/orgs/Routes.svelte';
+
  import Users from '@app/base/users/Routes.svelte';
  import Projects from '@app/base/projects/Routes.svelte';
  import Resolver from '@app/base/resolver/Routes.svelte';
  import Header from '@app/Header.svelte';
@@ -61,6 +62,7 @@
        </Route>
        <Registrations {config} session={$session} />
        <Orgs {config} />
+
        <Users {config} />
        <Projects {config} />
        <Resolver {config} />
      </Router>
added src/Avatar.svelte
@@ -0,0 +1,50 @@
+
<script lang="typescript">
+
  import { onMount } from 'svelte';
+
  import { createIcon } from '@app/blockies';
+
  import { isAddress } from '@app/utils';
+
  
+
  export let source: string;
+
  export let inline = false;
+
  export let glowOnHover = false;
+

+
  let container: HTMLElement;
+

+
  onMount(() => {
+
    if (isAddress(source)) {
+
      const seed = source.toLowerCase();
+
      const avatar = createIcon({
+
        seed,
+
        size: 8,
+
        scale: 16,
+
      });
+
      container.style.backgroundImage = `url(${avatar.toDataURL()})`;
+
    }
+
  });
+
</script>
+

+
<style>
+
  .avatar {
+
    border-radius: 50%;
+
    min-width: 1rem;
+
    min-height: 1rem;
+
    width: 100%;
+
    height: 100%;
+
    background-size: cover;
+
    background-repeat: no-repeat;
+
  }
+
  .avatar.glowOnHover:hover {
+
    box-shadow: 0 0 3rem var(--color-secondary);
+
  }
+
  .inline {
+
    display: inline-block;
+
    width: 1rem;
+
    height: 1rem;
+
    margin-right: 0.5rem;
+
  }
+
</style>
+

+
{#if isAddress(source)}
+
  <div class="avatar" class:inline bind:this={container} class:glowOnHover title={source}/>
+
{:else}
+
  <img class="avatar" class:inline src={source} class:glowOnHover alt="avatar"/>
+
{/if}
added src/base/users/Routes.svelte
@@ -0,0 +1,11 @@
+
<script lang="typescript">
+
  import { Route } from "svelte-routing";
+
  import View from '@app/base/users/View.svelte';
+
  import type { Config } from '@app/config';
+

+
  export let config: Config;
+
</script>
+

+
<Route path="/users/:address" let:params>
+
  <View {config} address={params.address}/>
+
</Route>
added src/base/users/View.svelte
@@ -0,0 +1,83 @@
+
<script lang="typescript">
+
  import { onMount } from 'svelte';
+
  import type { Config } from '@app/config';
+
  import type { Registration } from '@app/base/registrations/registrar';
+
  import { getRegistration } from '@app/base/registrations/registrar';
+
  import Icon from '@app/Icon.svelte';
+
  import Address from '@app/Address.svelte';
+
  import Avatar from '@app/Avatar.svelte';
+

+
  export let address: string;
+
  export let config: Config;
+
  
+
  let addressName: string | null = null;
+
  let info: Registration | null;
+
  
+
  onMount(async () => {
+
    addressName = await config.provider.lookupAddress(address);
+
    info = await getRegistration(addressName, config);
+
  });
+
</script>
+

+
<style>
+
  main {
+
    padding: 5rem 0;
+
  }
+
  main > header {
+
    display: flex;
+
    align-items: center;
+
    justify-content: left;
+
    margin-bottom: 2rem;
+
  }
+
  main > header > * {
+
    margin: 0 1rem 0 0;
+
  }
+
  .info {
+
    display: flex;
+
    flex-direction: column;
+
    justify-content: center;
+
    align-items: left;
+
  }
+
  .info a {
+
    border: none;
+
  }
+
  .avatar {
+
    width: 64px;
+
    height: 64px;
+
  }
+
  .links {
+
    display: flex;
+
    align-items: center;
+
    justify-content: left;
+
  }
+
  .url {
+
    display: flex; /* Ensures correct vertical positioning of icons */
+
    margin-right: 1rem;
+
  }
+
</style>
+

+
<main>
+
  <header>
+
    <div class="avatar">
+
      <Avatar source={info?.avatar ?? address} />
+
    </div> 
+
    <div class="info">
+
      <span class="title bold"><Address noAvatar {address} {config} resolve/></span>
+
        <div class="links">
+
          {#if info?.url}
+
            <a class="url" href={info.url}>{info.url}</a>
+
          {/if}
+
          {#if info?.twitter}
+
            <a class="url" href={info.twitter}>
+
              <Icon name="twitter" />
+
            </a>
+
          {/if}
+
          {#if info?.github}
+
            <a class="url" href={info.github}>
+
              <Icon name="github" />
+
            </a>
+
          {/if}
+
        </div>
+
      </div>
+
    </header> 
+
  </main>