text: import React, { useState, useMemo } from 'react';
  import Toolbar from '@material-ui/core/Toolbar';
  import AppBar from '@material-ui/core/AppBar';
  import Typography from '@material-ui/core/Typography';
  import { makeStyles } from '@material-ui/core/styles';
  import { useConnectionConfig } from '../utils/connection';
  import {
    clusterForEndpoint,
    getClusters,
    addCustomCluster,
    customClusterExists,
  } from '../utils/clusters';
  import Button from '@material-ui/core/Button';
  import Menu from '@material-ui/core/Menu';
  import MenuItem from '@material-ui/core/MenuItem';
  import { useWalletSelector } from '../utils/wallet';
  import ListItemIcon from '@material-ui/core/ListItemIcon';
  import CheckIcon from '@material-ui/icons/Check';
  import AddIcon from '@material-ui/icons/Add';
  import ExitToApp from '@material-ui/icons/ExitToApp';
  import AccountIcon from '@material-ui/icons/AccountCircle';
  import UsbIcon from '@material-ui/icons/Usb';
  import Divider from '@material-ui/core/Divider';
  import Hidden from '@material-ui/core/Hidden';
  import IconButton from '@material-ui/core/IconButton';
  import SolanaIcon from './SolanaIcon';
  import CodeIcon from '@material-ui/icons/Code';
  import Tooltip from '@material-ui/core/Tooltip';
  import ImportExportIcon from '@material-ui/icons/ImportExport';
  import AddAccountDialog from './AddAccountDialog';
  import DeleteMnemonicDialog from './DeleteMnemonicDialog';
  import AddHardwareWalletDialog from './AddHarwareWalletDialog';
  import { ExportMnemonicDialog } from './ExportAccountDialog.js';
  import {
    isExtension,
    isExtensionPopup,
    useIsExtensionWidth,
  } from '../utils/utils';
  import ConnectionIcon from './ConnectionIcon';
  import { Badge } from '@material-ui/core';
  import { useConnectedWallets } from '../utils/connected-wallets';
  import { usePage } from '../utils/page';
  import { MonetizationOn, OpenInNew } from '@material-ui/icons';
  import AddCustomClusterDialog from './AddCustomClusterDialog';
  
  const useStyles = makeStyles((theme) => ({
    content: {
      flexGrow: 1,
      paddingBottom: theme.spacing(3),
      [theme.breakpoints.up(theme.ext)]: {
        paddingTop: theme.spacing(3),
        paddingLeft: theme.spacing(1),
        paddingRight: theme.spacing(1),
      },
    },
    title: {
      flexGrow: 1,
    },
    button: {
      marginLeft: theme.spacing(1),
    },
    menuItemIcon: {
      minWidth: 32,
    },
    badge: {
      backgroundColor: theme.palette.success.main,
      color: theme.palette.text.main,
      height: 16,
      width: 16,
    },
  }));
  
  export default function NavigationFrame({ children }) {
    const classes = useStyles();
    const isExtensionWidth = useIsExtensionWidth();
    return (
      <>
        <AppBar position="static">
          {!isExtension && (
            <div
              style={{
                textAlign: 'center',
                background: '#fafafa',
                color: 'black',
                paddingLeft: '24px',
                paddingRight: '24px',
                fontSize: '14px',
              }}
            >
              <Typography>
                Beware of sites attempting to impersonate sollet.io or other DeFi
                services.
              </Typography>
            </div>
          )}
          <Toolbar>
            <Typography variant="h6" className={classes.title} component="h1">
              {isExtensionWidth ? 'Sollet' : 'Solana SPL Token Wallet'}
            </Typography>
            <NavigationButtons />
          </Toolbar>
        </AppBar>
        <main className={classes.content}>{children}</main>
        {!isExtensionWidth && <Footer />}
      </>
    );
  }
  
  function NavigationButtons() {
    const isExtensionWidth = useIsExtensionWidth();
    const [page] = usePage();
  
    if (isExtensionPopup) {
      return null;
    }
  
    let elements = [];
    if (page === 'wallet') {
      elements = [
        isExtension && <ConnectionsButton />,
        <WalletSelector />,
        <NetworkSelector />,
      ];
    } else if (page === 'connections') {
      elements = [<WalletButton />];
    }
  
    if (isExtension && isExtensionWidth) {
      elements.push(<ExpandButton />);
    }
  
    return elements;
  }
  
  function ExpandButton() {
    const onClick = () => {
      window.open(chrome.extension.getURL('index.html'), '_blank');
    };
  
    return (
      <Tooltip title="Expand View">
        <IconButton color="inherit" onClick={onClick}>
          <OpenInNew />
        </IconButton>
      </Tooltip>
    );
  }
  
  function WalletButton() {
    const classes = useStyles();
    const setPage = usePage()[1];
    const onClick = () => setPage('wallet');
  
    return (
      <>
        <Hidden smUp>
          <Tooltip title="Wallet Balances">
            <IconButton color="inherit" onClick={onClick}>
              <MonetizationOn />
            </IconButton>
          </Tooltip>
        </Hidden>
        <Hidden xsDown>
          <Button color="inherit" onClick={onClick} className={classes.button}>
            Wallet
          </Button>
        </Hidden>
      </>
    );
  }
  
  function ConnectionsButton() {
    const classes = useStyles();
    const setPage = usePage()[1];
    const onClick = () => setPage('connections');
    const connectedWallets = useConnectedWallets();
  
    const connectionAmount = Object.keys(connectedWallets).length;
  
    return (
      <>
        <Hidden smUp>
          <Tooltip title="Manage Connections">
            <IconButton color="inherit" onClick={onClick}>
              <Badge
                badgeContent={connectionAmount}
                classes={{ badge: classes.badge }}
              >
                <ConnectionIcon />
              </Badge>
            </IconButton>
          </Tooltip>
        </Hidden>
        <Hidden xsDown>
          <Badge
            badgeContent={connectionAmount}
            classes={{ badge: classes.badge }}
          >
            <Button color="inherit" onClick={onClick} className={classes.button}>
              Connections
            </Button>
          </Badge>
        </Hidden>
      </>
    );
  }
  
  function NetworkSelector() {
    const { endpoint, setEndpoint } = useConnectionConfig();
    const cluster = useMemo(() => clusterForEndpoint(endpoint), [endpoint]);
    const [anchorEl, setAnchorEl] = useState(null);
    const [addCustomNetworkOpen, setCustomNetworkOpen] = useState(false);
    const classes = useStyles();
  
    return (
      <>
        <AddCustomClusterDialog
          open={addCustomNetworkOpen}
          onClose={() => setCustomNetworkOpen(false)}
          onAdd={({ name, apiUrl }) => {
            addCustomCluster(name, apiUrl);
            setCustomNetworkOpen(false);
          }}
        />
        <Hidden xsDown>
          <Button
            color="inherit"
            onClick={(e) => setAnchorEl(e.target)}
            className={classes.button}
          >
            {cluster?.label ?? 'Network'}
          </Button>
        </Hidden>
        <Hidden smUp>
          <Tooltip title="Select Network" arrow>
            <IconButton color="inherit" onClick={(e) => setAnchorEl(e.target)}>
              <SolanaIcon />
            </IconButton>
          </Tooltip>
        </Hidden>
        <Menu
          anchorEl={anchorEl}
          open={!!anchorEl}
          onClose={() => setAnchorEl(null)}
          anchorOrigin={{
            vertical: 'bottom',
            horizontal: 'right',
          }}
          getContentAnchorEl={null}
        >
          {getClusters().map((cluster) => (
            <MenuItem
              key={cluster.apiUrl}
              onClick={() => {
                setAnchorEl(null);
                setEndpoint(cluster.apiUrl);
              }}
              selected={cluster.apiUrl === endpoint}
            >
              <ListItemIcon className={classes.menuItemIcon}>
                {cluster.apiUrl === endpoint ? (
                  <CheckIcon fontSize="small" />
                ) : null}
              </ListItemIcon>
              {cluster.name === 'mainnet-beta-backup'
                ? 'Mainnet Beta Backup'
                : cluster.apiUrl}
            </MenuItem>
          ))}
          <MenuItem
            onClick={() => {
              setCustomNetworkOpen(true);
            }}
          >
            <ListItemIcon className={classes.menuItemIcon}></ListItemIcon>
            {customClusterExists()
              ? 'Edit Custom Endpoint'
              : 'Add Custom Endpoint'}
          </MenuItem>
        </Menu>
      </>
    );
  }
  
  function WalletSelector() {
    const {
      accounts,
      derivedAccounts,
      hardwareWalletAccount,
      setHardwareWalletAccount,
      setWalletSelector,
      addAccount,
    } = useWalletSelector();
    const [anchorEl, setAnchorEl] = useState(null);
    const [addAccountOpen, setAddAccountOpen] = useState(false);
    const [addHardwareWalletDialogOpen, setAddHardwareWalletDialogOpen] =
      useState(false);
    const [deleteMnemonicOpen, setDeleteMnemonicOpen] = useState(false);
    const [exportMnemonicOpen, setExportMnemonicOpen] = useState(false);
    const classes = useStyles();
  
    if (accounts.length === 0) {
      return null;
    }
    return (
      <>
        <AddHardwareWalletDialog
          open={addHardwareWalletDialogOpen}
          onClose={() => setAddHardwareWalletDialogOpen(false)}
          onAdd={({ publicKey, derivationPath, account, change }) => {
            setHardwareWalletAccount({
              name: 'Hardware wallet',
              publicKey,
              importedAccount: publicKey.toString(),
              ledger: true,
              derivationPath,
              account,
              change,
            });
            setWalletSelector({
              walletIndex: undefined,
              importedPubkey: publicKey.toString(),
              ledger: true,
              derivationPath,
              account,
              change,
            });
          }}
        />
        <AddAccountDialog
          open={addAccountOpen}
          onClose={() => setAddAccountOpen(false)}
          onAdd={({ name, importedAccount }) => {
            addAccount({ name, importedAccount });
            setWalletSelector({
              walletIndex: importedAccount ? undefined : derivedAccounts.length,
              importedPubkey: importedAccount
                ? importedAccount.publicKey.toString()
                : undefined,
              ledger: false,
            });
            setAddAccountOpen(false);
          }}
        />
        <ExportMnemonicDialog
          open={exportMnemonicOpen}
          onClose={() => setExportMnemonicOpen(false)}
        />
        <DeleteMnemonicDialog
          open={deleteMnemonicOpen}
          onClose={() => setDeleteMnemonicOpen(false)}
        />
        <Hidden xsDown>
          <Button
            color="inherit"
            onClick={(e) => setAnchorEl(e.target)}
            className={classes.button}
          >
            Account
          </Button>
        </Hidden>
        <Hidden smUp>
          <Tooltip title="Select Account" arrow>
            <IconButton color="inherit" onClick={(e) => setAnchorEl(e.target)}>
              <AccountIcon />
            </IconButton>
          </Tooltip>
        </Hidden>
        <Menu
          anchorEl={anchorEl}
          open={!!anchorEl}
          onClose={() => setAnchorEl(null)}
          anchorOrigin={{
            vertical: 'bottom',
            horizontal: 'right',
          }}
          getContentAnchorEl={null}
        >
          {accounts.map((account) => (
            <AccountListItem
              account={account}
              classes={classes}
              setAnchorEl={setAnchorEl}
              setWalletSelector={setWalletSelector}
            />
          ))}
          {hardwareWalletAccount && (
            <>
              <Divider />
              <AccountListItem
                account={hardwareWalletAccount}
                classes={classes}
                setAnchorEl={setAnchorEl}
                setWalletSelector={setWalletSelector}
              />
            </>
          )}
          <Divider />
          <MenuItem onClick={() => setAddHardwareWalletDialogOpen(true)}>
            <ListItemIcon className={classes.menuItemIcon}>
              <UsbIcon fontSize="small" />
            </ListItemIcon>
            Import Hardware Wallet
          </MenuItem>
          <MenuItem
            onClick={() => {
              setAnchorEl(null);
              setAddAccountOpen(true);
            }}
          >
            <ListItemIcon className={classes.menuItemIcon}>
              <AddIcon fontSize="small" />
            </ListItemIcon>
            Add Account
          </MenuItem>
          <MenuItem
            onClick={() => {
              setAnchorEl(null);
              setExportMnemonicOpen(true);
            }}
          >
            <ListItemIcon className={classes.menuItemIcon}>
              <ImportExportIcon fontSize="small" />
            </ListItemIcon>
            Export Mnemonic
          </MenuItem>
          <MenuItem
            onClick={() => {
              setAnchorEl(null);
              setDeleteMnemonicOpen(true);
            }}
          >
            <ListItemIcon className={classes.menuItemIcon}>
              <ExitToApp fontSize="small" />
            </ListItemIcon>
            {'Delete Mnemonic & Log Out'}
          </MenuItem>
        </Menu>
      </>
    );
  }
  
  const useFooterStyles = makeStyles((theme) => ({
    footer: {
      display: 'flex',
      justifyContent: 'flex-end',
      margin: theme.spacing(2),
    },
  }));
  
  function Footer() {
    const classes = useFooterStyles();
    return (
      <footer className={classes.footer}>
        <Button
          variant="outlined"
          color="primary"
          component="a"
          target="_blank"
          rel="noopener"
          href="https://github.com/serum-foundation/spl-token-wallet"
          startIcon={<CodeIcon />}
        >
          View Source
        </Button>
      </footer>
    );
  }
  
  function AccountListItem({ account, classes, setAnchorEl, setWalletSelector }) {
    return (
      <MenuItem
        key={account.address.toBase58()}
        onClick={() => {
          setAnchorEl(null);
          setWalletSelector(account.selector);
        }}
        selected={account.isSelected}
        component="div"
      >
        <ListItemIcon className={classes.menuItemIcon}>
          {account.isSelected ? <CheckIcon fontSize="small" /> : null}
        </ListItemIcon>
        <div style={{ display: 'flex', flexDirection: 'column' }}>
          <Typography>{account.name}</Typography>
          <Typography color="textSecondary">
            {account.address.toBase58()}
          </Typography>
        </div>
      </MenuItem>
    );
  }
  