Radish alpha
r
Radicle web interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
Add home page
Alexis Sellier committed 5 years ago
commit e6f8edc3f6ec98d86b8f7b558c4774ce3e7965ca
parent a54b0eb97599c0a4d705c0e8abe39e1c8f6204ef
10 files changed +104 -27
modified src/App.svelte
@@ -4,16 +4,13 @@
  import { getConfig } from '@app/config';
  import { session } from '@app/session';

+
  import Home from '@app/base/home/Home.svelte';
  import Vesting from '@app/base/vesting/Vesting.svelte';
  import Register from '@app/base/register/Routes.svelte';
  import Orgs from '@app/base/orgs/Routes.svelte';
+
  import Resolve from '@app/base/resolve/Routes.svelte';
  import Header from '@app/Header.svelte';

-
  const defaultPath = "register";
-
  const path = window.location.pathname;
-
  const query = new URLSearchParams(window.location.search);
-
  export let url = path === "/" ? defaultPath : path;
-

  function handleKeydown(event: KeyboardEvent) {
    if (event.key === 'Enter') {
      (document.querySelector('button.primary') as HTMLElement).click();
@@ -39,12 +36,16 @@
  <div class="app">
    <Header session={$session} {config} />
    <div class="wrapper">
-
      <Router url="{url}">
+
      <Router>
+
        <Route path="/">
+
          <Home />
+
        </Route>
        <Route path="vesting">
          <Vesting {config} session={$session} />
        </Route>
-
        <Register {config} {query} session={$session} />
+
        <Register {config} session={$session} />
        <Orgs {config} />
+
        <Resolve {config} />
      </Router>
    </div>
  </div>
modified src/Header.svelte
@@ -41,6 +41,8 @@
    margin-right: 1.5rem;
    font-weight: 500;
    color: var(--color-foreground-6);
+
  }
+
  header a {
    border: none;
  }
  header .nav a:hover {
@@ -84,7 +86,7 @@

<header>
  <div class="left">
-
    <Logo />
+
    <a use:link href="/"><Logo /></a>
    <div class="nav">
      <a use:link href="/register/">Register</a>
      <a use:link href="/vesting/">Vesting</a>
added src/base/home/Home.svelte
@@ -0,0 +1,17 @@
+
<script lang="typescript">
+
  import { navigate } from 'svelte-routing';
+

+
  let input: string = "";
+
  const search = () => {
+
    navigate(`/resolve?${
+
      new URLSearchParams({ q: input })
+
    }`);
+
  };
+
</script>
+

+
<main>
+
  <input size="40" type="text" bind:value={input} placeholder="Enter a name, address or domain..." />
+
  <button class="primary" on:click={search} disabled={!input}>
+
    Search
+
  </button>
+
</main>
modified src/base/register/Routes.svelte
@@ -7,23 +7,23 @@
  import Error from '@app/Error.svelte';
  import type { Config } from '@app/config';
  import type { Session } from '@app/session';
+
  import { getSearchParam } from '@app/utils';

  export let session: Session | null;
  export let config: Config;
-
  export let query: Record<string, any>;
</script>

<Route path="register">
  <Register {config} />
</Route>

-
<Route path="register/:name" let:params>
-
  <Begin {config} subdomain={params.name} {query} />
+
<Route path="register/:name" let:params let:location>
+
  <Begin {config} subdomain={params.name} owner={getSearchParam("owner", location)} />
</Route>

-
<Route path="register/:name/submit" let:params>
+
<Route path="register/:name/submit" let:params let:location>
  {#if session}
-
    <Submit {config} subdomain={params.name} {query} {session} />
+
    <Submit {config} subdomain={params.name} owner={getSearchParam("owner", location)} {session} />
  {:else}
    <Error
      message={"You must connect your wallet to register"}
modified src/base/register/steps/Begin.svelte
@@ -18,10 +18,10 @@

  export let config: Config;
  export let subdomain: string;
-
  export let query: Record<string, any>;
+
  export let owner: string | null;

  let state = State.Initial;
-
  $: registrationOwner = query.get("owner") || ($session && $session.address);
+
  $: registrationOwner = owner || ($session && $session.address);

  async function begin() {
    state = State.CheckingAvailability;
modified src/base/register/steps/Submit.svelte
@@ -3,8 +3,7 @@
  // TODO: When transfering name, warn about transfering to org.
  import { onMount } from 'svelte';
  import { navigate } from 'svelte-routing';
-
  import { ethers } from 'ethers';
-
  import { registerName, registrationFee } from '../registrar';
+
  import { registerName } from '../registrar';
  import { State, state } from '../state';
  import type { Session } from '@app/session';
  import type { Config } from '@app/config';
@@ -14,16 +13,11 @@

  export let config: Config;
  export let subdomain: string;
-
  export let query: Record<string, any>;
+
  export let owner: string | null;
  export let session: Session;

  let error: Error | null = null;
-
  let registrationOwner = query.get("owner") || session.address;
-

-
  async function getFee(cfg: Config) {
-
    let fee = await registrationFee(cfg);
-
    return ethers.utils.formatUnits(fee);
-
  }
+
  let registrationOwner = owner || session.address;

  const done = () => navigate(`/registrations/${subdomain}`)

added src/base/resolve/Resolve.svelte
@@ -0,0 +1,27 @@
+
<script lang="typescript">
+
  import { onMount } from 'svelte';
+
  import { ethers } from 'ethers';
+
  import { navigate } from 'svelte-routing';
+
  import type { Config } from '@app/config';
+
  import * as utils from '@app/utils';
+

+
  export let config: Config;
+
  export let query: string | null;
+

+
  onMount(() => {
+
    if (query) {
+
      if (ethers.utils.isAddress(query)) {
+
        // Go to org.
+
        navigate(`/orgs/${query}`, { replace: true });
+
      } else if (utils.isRadicleId(query)) {
+
        // Go to Radicle entity.
+
        alert("Radicle IDs are not yet supported");
+
      } else {
+
        let label = utils.parseEnsLabel(query, config);
+
        navigate(`/registrations/${label}`, { replace: true });
+
      }
+
    } else {
+
      navigate('/');
+
    }
+
  });
+
</script>
added src/base/resolve/Routes.svelte
@@ -0,0 +1,12 @@
+
<script lang="typescript">
+
  import { Route } from "svelte-routing";
+
  import Resolve from '@app/base/resolve/Resolve.svelte';
+
  import type { Config } from '@app/config';
+
  import * as utils from '@app/utils';
+

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

+
<Route path="/resolve" let:location>
+
  <Resolve {config} query={utils.getSearchParam("q", location)} />
+
</Route>
modified src/index.ts
@@ -1,5 +1,17 @@
import App from "./App.svelte";

+
declare global {
+
  // Taken from svelte-routing, since it's not exported.
+
  interface RouteLocation {
+
    pathname: string;
+
    search: string;
+
    hash?: string;
+
    state: {
+
      [k in string | number]: unknown;
+
    };
+
  }
+
}
+

let app = new App({
  target: document.body,
});
modified src/utils.ts
@@ -18,13 +18,25 @@ export function capitalize(s: string) {
}

// Takes a domain name, eg. 'cloudhead.radicle.eth' and
-
// returns the label, eg. 'cloudhead'.
-
export function parseEnsLabel(name: string, config: Config) {
+
// returns the label, eg. 'cloudhead', otherwise `null`.
+
export function parseEnsLabel(name: string, config: Config): string | null {
  let domain = config.registrar.domain.replace(".", "\\.");
-
  return name.replace(new RegExp(`\\.${domain}$`), "");
+
  let label = name.replace(new RegExp(`\\.${domain}$`), "");
+

+
  return label;
}

// Return the current unix time.
export function unixTime(): number {
  return Math.floor(Date.now() / 1000);
}
+

+
// Check whether the input is a Radicle ID.
+
export function isRadicleId(input: string): boolean {
+
  return /^rad:[a-z]+:[a-zA-Z0-9]+$/.test(input);
+
}
+

+
export function getSearchParam(key: string, location: RouteLocation): string | null {
+
  let params = new URLSearchParams(location.search);
+
  return params.get(key);
+
};