Skip to content

Commit

Permalink
Support editing account name in account list
Browse files Browse the repository at this point in the history
  • Loading branch information
limemloh committed Oct 24, 2024
1 parent a099cd9 commit 81e611c
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 9 deletions.
3 changes: 3 additions & 0 deletions packages/browser-wallet/src/assets/svgX/checkmark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,25 @@
overflow-wrap: anywhere;
}

input.editable {
background: none;
color: inherit;
border: none;
font-weight: inherit;
font-size: inherit;
font-family: inherit;
padding: 0;
margin: 0;

&:focus {
outline: none;
}
}

.button__icon {
gap: rem(16px);
height: rem(16px);
width: rem(16px);

.label__main {
color: $color-white;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React from 'react';
import React, { ChangeEvent, KeyboardEvent, useState } from 'react';
import Plus from '@assets/svgX/plus.svg';
import Arrows from '@assets/svgX/arrows-down-up.svg';
import MagnifyingGlass from '@assets/svgX/magnifying-glass.svg';
import Pencil from '@assets/svgX/pencil-simple.svg';
import Checkmark from '@assets/svgX/checkmark.svg';
import Close from '@assets/svgX/close.svg';
import Copy from '@assets/svgX/copy.svg';
import ArrowRight from '@assets/svgX/arrow-right.svg';
import Page from '@popup/popupX/shared/Page';
Expand All @@ -16,14 +18,73 @@ import { copyToClipboard } from '@popup/popupX/shared/utils/helpers';
import { useAtomValue } from 'jotai';
import { credentialsAtom } from '@popup/store/account';
import { WalletCredential } from '@shared/storage/types';
import { useIdentityName } from '@popup/shared/utils/account-helpers';
import { useIdentityName, useWritableSelectedAccount } from '@popup/shared/utils/account-helpers';
import { useAccountInfo } from '@popup/shared/AccountInfoListenerContext';
import { displayAsCcd } from 'wallet-common-helpers';

function fallbackAccountName(credentialNumber: number): string {
return `Account ${1 + credentialNumber}`;
}

type EditableAccountNameProps = {
currentName: string;
fallbackName: string;
onNewName: (newName: string) => void;
};

function EditableAccountName({ currentName, fallbackName, onNewName }: EditableAccountNameProps) {
const [isEditingName, setIsEditingName] = useState(false);
const [editedName, setEditedName] = useState(currentName);
// Using editedName instead of currentName to avoid flickering after completing.
const displayName = editedName === '' ? fallbackName : editedName;
const onAbort = () => {
setIsEditingName(false);
setEditedName(currentName);
};
const onComplete = () => {
onNewName(editedName.trim());
setIsEditingName(false);
};
const onEdit = () => {
setEditedName(currentName);
setIsEditingName(true);
};
const onInputChange = (event: ChangeEvent<HTMLInputElement>) => {
setEditedName(event.target.value);
};
const onKeyUp = (event: KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'Enter') {
event.preventDefault();
onComplete();
}
};
if (isEditingName) {
return (
<>
<Text.Main>
<input
autoFocus
className="editable"
value={editedName}
placeholder={fallbackName}
onChange={onInputChange}
onKeyUp={onKeyUp}
maxLength={25}
/>
</Text.Main>
<Button.Icon className="transparent" icon={<Checkmark />} onClick={onComplete} />
<Button.Icon className="transparent" icon={<Close />} onClick={onAbort} />
</>
);
}
return (
<>
<Text.Main>{displayName}</Text.Main>
<Button.Icon className="transparent" icon={<Pencil />} onClick={onEdit} />
</>
);
}

type AccountListItemProps = {
credential: WalletCredential;
};
Expand All @@ -34,19 +95,23 @@ function AccountListItem({ credential }: AccountListItemProps) {
const navToPrivateKey = () => nav(absoluteRoutes.settings.accounts.privateKey.path);
const navToConnectedSites = () => nav(absoluteRoutes.settings.accounts.connectedSites.path);
const navToIdCards = () => nav(absoluteRoutes.settings.idCards.path);

const identityName = useIdentityName(credential);
const accountInfo = useAccountInfo(credential);

const accountName = credential.credName !== '' ? credential.credName : fallbackAccountName(credential.credNumber);
const setAccount = useWritableSelectedAccount(credential.address);
const fallbackName = fallbackAccountName(credential.credNumber);
const accountName = credential.credName !== '' ? credential.credName : fallbackName;
const { address } = credential;
const ccdBalance =
accountInfo === undefined ? 'Loading' : displayAsCcd(accountInfo.accountAmount.microCcdAmount, false);
const onNewAccountName = (newName: string) => setAccount({ credName: newName });
return (
<Card key={accountName}>
<Card.Row>
<Text.Main>{accountName}</Text.Main>
<Button.Icon className="transparent" icon={<Pencil />} />
<EditableAccountName
currentName={accountName}
onNewName={onNewAccountName}
fallbackName={fallbackName}
/>
</Card.Row>
<Card.Row>
<Text.Capture>{address}</Text.Capture>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,11 @@ export function useIdentityName(credential: WalletCredential, fallback?: string)

export function useWritableSelectedAccount(accountAddress: string) {
const [accounts, setAccounts] = useAtom(writableCredentialAtom);
const setAccount = (update: WalletCredential) =>
const setAccount = (update: Partial<WalletCredential>) =>
setAccounts(
accounts.map((account) => (account.address === accountAddress ? { ...account, ...update } : account))
accounts.map((account) =>
account.address === accountAddress ? ({ ...account, ...update } as WalletCredential) : account
)
);

return setAccount;
Expand Down

0 comments on commit 81e611c

Please sign in to comment.