Skip to content

Commit

Permalink
Save crypto addresses (#4491)
Browse files Browse the repository at this point in the history
Co-authored-by: Hamish Peebles <[email protected]>
  • Loading branch information
julianjelfs and hpeebles authored Oct 5, 2023
1 parent 8d23269 commit 27e9aed
Show file tree
Hide file tree
Showing 23 changed files with 457 additions and 56 deletions.
2 changes: 2 additions & 0 deletions frontend/app/src/components/Menu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
box-shadow: var(--menu-sh);
border-radius: $sp2;
border: 1px solid var(--menu-bd);
max-height: 80vh;
overflow-y: auto;
@include mobile() {
&.centered {
Expand Down
16 changes: 14 additions & 2 deletions frontend/app/src/components/MenuItem.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
export let selected: boolean = false;
export let warning: boolean = false;
export let separator: boolean = false;
export let unpadded: boolean = false;
</script>

{#if disabled}
<div class:disabled class="menu-item" role="menuitem">
<div class:unpadded class:disabled class="menu-item" role="menuitem">
<span class="icon">
<slot name="icon" />
</span>
Expand All @@ -15,7 +16,14 @@
{:else if separator}
<hr class="separator" />
{:else}
<div tabindex="0" class="menu-item" on:click role="menuitem" class:selected class:warning>
<div
class:unpadded
tabindex="0"
class="menu-item"
on:click
role="menuitem"
class:selected
class:warning>
<span class="icon">
<slot name="icon" />
</span>
Expand All @@ -33,6 +41,10 @@
padding: 10px;
gap: 10px;
&.unpadded {
padding: 0;
}
&:last-child {
border-bottom: none;
}
Expand Down
102 changes: 102 additions & 0 deletions frontend/app/src/components/home/profile/AccountSelector.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<script lang="ts">
import { _ } from "svelte-i18n";
import type { NamedAccount } from "openchat-client";
import ChevronDown from "svelte-material-icons/ChevronDown.svelte";
import { iconSize } from "../../../stores/iconSize";
import MenuIcon from "../../MenuIcon.svelte";
import Menu from "../../Menu.svelte";
import MenuItem from "../../MenuItem.svelte";
import { mobileWidth } from "../../../stores/screenDimensions";
export let accounts: NamedAccount[];
export let targetAccount: string;
let selectedName: string | undefined = undefined;
let menuIcon: MenuIcon;
$: {
selectedName = accounts.find((a) => {
return a.account.toLowerCase() === targetAccount.toLowerCase();
})?.name;
}
function collapseAccount(account: string) {
if (account.length > 23) {
return account.slice(0, 10) + "..." + account.slice(account.length - 10);
}
return account;
}
function selectAccount(namedAccount: NamedAccount) {
targetAccount = namedAccount.account;
}
function showMenu() {
menuIcon.showMenu();
}
</script>

<div role="combobox" tabindex="0" class="selected" on:click|stopPropagation={showMenu}>
<div class="name">
{selectedName ?? $_("tokenTransfer.chooseAddress")}
</div>
<div class="icon">
<MenuIcon bind:this={menuIcon} position={$mobileWidth ? "top" : "bottom"} align={"end"}>
<div slot="icon">
<ChevronDown viewBox={"0 -3 24 24"} size={$iconSize} color={"var(--icon-txt)"} />
</div>
<div slot="menu">
<Menu>
{#each accounts as namedAccount}
<MenuItem unpadded on:click={() => selectAccount(namedAccount)}>
<div slot="text" class="named-account">
<div class="name">
{namedAccount.name}
</div>
<div class="account">
{collapseAccount(namedAccount.account)}
</div>
</div>
</MenuItem>
{/each}
</Menu>
</div>
</MenuIcon>
</div>
</div>

<style lang="scss">
.selected {
display: flex;
align-items: center;
gap: $sp3;
cursor: pointer;
@include font(book, normal, fs-80);
.name {
color: var(--primary);
}
.icon {
transition: transform 250ms ease-in-out;
transform-origin: 50%;
}
}
.named-account {
padding: $sp3;
display: flex;
flex-direction: column;
@include font(book, normal, fs-80);
font-family: "Roboto", sans-serif;
.name {
color: var(--primary);
}
.account {
@include font(light, normal, fs-70);
color: var(--menu-disabled-txt);
}
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
let error: string | undefined = undefined;
let amountToSend = BigInt(0);
let balanceWithRefresh: BalanceWithRefresh;
let sending = false;
let busy = false;
let capturingAccount = false;
let valid = false;
$: cryptoLookup = client.cryptoLookup;
Expand All @@ -49,6 +50,24 @@
function onBalanceRefreshError(ev: CustomEvent<string>) {
error = ev.detail;
}
function saveAccount() {
if (sendCrypto) {
busy = true;
sendCrypto
.saveAccount()
.then((resp) => {
if (resp.kind === "success") {
dispatch("close");
} else if (resp.kind === "name_taken") {
error = "tokenTransfer.accountNameTaken";
} else {
error = "tokenTransfer.failedToSaveAccount";
}
})
.finally(() => (busy = false));
}
}
</script>

<Overlay on:close dismissible>
Expand Down Expand Up @@ -76,8 +95,10 @@
{#if mode === "send"}
<SendCrypto
bind:this={sendCrypto}
bind:sending
bind:busy
bind:capturingAccount
bind:valid
on:close
on:error={(ev) => (error = ev.detail)}
on:refreshBalance={() => balanceWithRefresh.refresh()}
{ledger}
Expand All @@ -90,13 +111,23 @@
<span slot="footer">
<ButtonGroup>
{#if mode === "send"}
<Button secondary tiny={$mobileWidth} on:click={() => dispatch("close")}
>{$_("cancel")}</Button>
<Button
disabled={sending || !valid}
loading={sending}
tiny={$mobileWidth}
on:click={() => sendCrypto?.send()}>{$_("tokenTransfer.send")}</Button>
{#if capturingAccount}
<Button secondary tiny={$mobileWidth} on:click={() => dispatch("close")}
>{$_("noThanks")}</Button>
<Button
disabled={busy || !valid}
loading={busy}
tiny={$mobileWidth}
on:click={saveAccount}>{$_("tokenTransfer.saveAccount")}</Button>
{:else}
<Button secondary tiny={$mobileWidth} on:click={() => dispatch("close")}
>{$_("cancel")}</Button>
<Button
disabled={busy || !valid}
loading={busy}
tiny={$mobileWidth}
on:click={() => sendCrypto?.send()}>{$_("tokenTransfer.send")}</Button>
{/if}
{:else}
<Button tiny={$mobileWidth} on:click={() => dispatch("close")}
>{$_("close")}</Button>
Expand Down
47 changes: 47 additions & 0 deletions frontend/app/src/components/home/profile/SaveAccount.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<script lang="ts">
import type { NamedAccount, OpenChat } from "openchat-client";
import Input from "../../Input.svelte";
import { getContext } from "svelte";
import { _ } from "svelte-i18n";
import Legend from "../../Legend.svelte";
const client = getContext<OpenChat>("client");
export let account: string;
export let accounts: NamedAccount[];
export let valid = false;
let name = "";
$: trimmedName = name.trim();
$: {
valid =
trimmedName.length > 0 &&
accounts.find((a) => a.name.toLowerCase() === trimmedName.toLowerCase()) === undefined;
}
export function saveAccount() {
return client.saveCryptoAccount({
account,
name: trimmedName,
});
}
</script>

<Legend label={$_("tokenTransfer.saveAccountMessage")} />

<p class="account">{account}</p>

<Input
bind:value={name}
autofocus
countdown={false}
maxlength={100}
placeholder={$_("tokenTransfer.enterAccountName")} />

<style lang="scss">
.account {
@include input();
margin-bottom: $sp3;
}
</style>
Loading

0 comments on commit 27e9aed

Please sign in to comment.