diff --git a/cashtab/package-lock.json b/cashtab/package-lock.json --- a/cashtab/package-lock.json +++ b/cashtab/package-lock.json @@ -1,12 +1,12 @@ { "name": "cashtab", - "version": "2.24.1", + "version": "2.24.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cashtab", - "version": "2.24.1", + "version": "2.24.2", "dependencies": { "@ant-design/icons": "^5.3.0", "@bitgo/utxo-lib": "^9.33.0", diff --git a/cashtab/package.json b/cashtab/package.json --- a/cashtab/package.json +++ b/cashtab/package.json @@ -1,6 +1,6 @@ { "name": "cashtab", - "version": "2.24.1", + "version": "2.24.2", "private": true, "scripts": { "start": "node scripts/start.js", diff --git a/cashtab/src/components/Alias/Alias.js b/cashtab/src/components/Alias/Alias.js --- a/cashtab/src/components/Alias/Alias.js +++ b/cashtab/src/components/Alias/Alias.js @@ -7,25 +7,14 @@ import { WalletContext } from 'wallet/context'; import PropTypes from 'prop-types'; import { AlertMsg } from 'components/Common/Atoms'; -import { PendingAliasWarningIcon } from 'components/Common/CustomIcons'; -import { - AntdFormWrapper, - AliasInput, - AliasAddressInput, - CashtabCheckbox, -} from 'components/Common/EnhancedInputs'; import { AliasRegisterIcon } from 'components/Common/CustomIcons'; -import { Form, Modal } from 'antd'; import PrimaryButton from 'components/Common/PrimaryButton'; -import { Row, Col } from 'antd'; import { getWalletState } from 'utils/cashMethods'; import { toXec } from 'wallet'; import { meetsAliasSpec } from 'validation'; import { queryAliasServer } from 'alias'; import cashaddr from 'ecashaddrjs'; -import { Space, Tag } from 'antd'; import CopyToClipboard from 'components/Common/CopyToClipboard'; -import { CustomCollapseCtn } from 'components/Common/StyledCollapse'; import appConfig from 'config/app'; import aliasSettings from 'config/alias'; import { explorer } from 'config/explorer'; @@ -33,12 +22,64 @@ import { sendXec } from 'transactions'; import { hasEnoughToken } from 'wallet'; import { toast } from 'react-toastify'; - -export const CheckboxContainer = styled.div` - text-align: left; +import { AliasInput, Input } from 'components/Common/Inputs'; +import Switch from 'components/Common/Switch'; +import Modal from 'components/Common/Modal'; + +const AliasWrapper = styled.div` + color: ${props => props.theme.contrast}; + margin: 12px 0; + box-sizing: border-box; + *, + *:before, + *:after { + box-sizing: inherit; + } +`; +export const SwitchContainer = styled.div` + display: flex; margin-bottom: 12px; + justify-content: flex-start; + align-items: center; + gap: 12px; +`; +const SwitchLabel = styled.div` + display: flex; + font-size: 16px; +`; +const AltAddressHolder = styled.div` + display: flex; + margin-bottom: 12px; +`; +const AliasHeader = styled.div` + color: ${props => props.theme.contrast}; + font-weight: bold; + font-size: 20px; + margin: 12px 0; + width: 100%; +`; +const Panel = styled.div` + display: flex; + flex-wrap: wrap; + padding: 12px; + width: 100%; + background-color: ${props => props.theme.panel}; + border-radius: 9px; + margin-bottom: 12px; + gap: 12px; +`; +const AliasTag = styled.div` + display: flex; + color: ${props => props.theme.contrast}; + background-color: #0074c2; + &:hover { + background-color: ${props => props.theme.eCashPurple}; + } + gap: 12px; + border-radius: 3px; + padding: 3px; + font-size: 12px; `; - // Change mouse cursor to pointer upon hovering over an Alias tag export const AliasLabel = styled.div` cursor: pointer; @@ -73,13 +114,6 @@ white-space: pre-wrap; `; -const StyledSpacer = styled.div` - height: 1px; - width: 100%; - background-color: ${props => props.theme.lightWhite}; - margin: 60px 0 50px; -`; - const Alias = ({ passLoadingStatus }) => { const ContextValue = React.useContext(WalletContext); const { @@ -100,9 +134,9 @@ const { balanceSats, tokens } = walletState; const [formData, setFormData] = useState({ aliasName: '', - aliasAddress: '', + aliasAddress: defaultAddress, }); - const [useThisAddressChecked, setUseThisAddressChecked] = useState(false); + const [registerActiveWallet, setRegisterActiveWallet] = useState(true); const [isValidAliasInput, setIsValidAliasInput] = useState(false); // tracks whether to activate the registration button const [isValidAliasAddressInput, setIsValidAliasAddressInput] = useState(false); // tracks whether to activate the registration button @@ -119,6 +153,26 @@ passLoadingStatus(false); }, [balanceSats]); + useEffect(() => { + if (registerActiveWallet) { + // Set address of active wallet to default alias registration address + handleAliasAddressInput({ + target: { + name: 'aliasAddress', + value: defaultAddress, + }, + }); + } else { + // Clear the form if the user unchecks + handleAliasAddressInput({ + target: { + name: 'aliasAddress', + value: '', + }, + }); + } + }, [registerActiveWallet]); + const handleAliasWalletChange = async () => { if (defaultAddress !== '') { await refreshAliases(defaultAddress); @@ -177,11 +231,6 @@ } passLoadingStatus(true); - // Default to registering the user's active wallet - // Must be called in this useEffect to ensure that wallet is loaded - // Call with this function to ensure that checkbox state and checkbox are updated - handleDefaultAddressCheckboxChange({ target: { checked: true } }); - // passLoadingStatus(false) will be called after awaiting expected methods handleAliasWalletChange(); }, [wallet.name]); @@ -361,39 +410,6 @@ })); }; - const handleDefaultAddressCheckboxChange = e => { - /* handleDefaultAddressCheckboxChange - * - * Function to handle user action of checking or unchecking the - * checkbox on this page labeled 'Register active wallet address' - * - * May be called programmatically by mocking the usual js event - * of a user checking the box - * - * If the box is checked, set formData for aliasAddress to the active wallet's address - * If the box is unchecked, clear formData for aliasAddress - */ - const checked = e.target.checked; - setUseThisAddressChecked(checked); - if (checked) { - // Set address of active wallet to default alias registration address - handleAliasAddressInput({ - target: { - name: 'aliasAddress', - value: defaultAddress, - }, - }); - } else { - // Clear the form if the user unchecks - handleAliasAddressInput({ - target: { - name: 'aliasAddress', - value: '', - }, - }); - } - }; - const handleAliasAddressInput = e => { /* handleAliasAddressInput * @@ -439,260 +455,169 @@ return ( <> - - - - {' '} - Warning: pending registrations detected - - - ) : ( - - Confirm alias registration - - ) - } - open={isModalVisible} - onOk={handleOk} - onCancel={handleCancel} - > - {!aliasWarningMsg && - aliasDetails && - Number.isInteger(aliasDetails.registrationFeeSats) && ( - - {`The alias ${ - formData.aliasName - } is available and can be registered for ${toXec( - aliasDetails.registrationFeeSats, - ).toLocaleString()} XEC. Proceed with registration?`} - - )} - {aliasWarningMsg !== false && - aliasDetails && - Number.isInteger(aliasDetails.registrationFeeSats) && ( - <> - - - {` Warning: ${aliasWarningMsg}`} -
-
- {` Continue the registration anyway for ${toXec( - aliasDetails.registrationFeeSats, - ).toLocaleString()} XEC?`} -
-
- - )} - {!useThisAddressChecked && - !aliasAddressValidationError && - ` Please also note Cashtab will only track alias registrations for ${wallet.name}: ${defaultAddress}.`} -
- - - -

eCash Namespace Alias

-
- -
- - handleAliasNameInput(e), - required: true, - }} - /> - {(() => { - let aliasLength = getAliasByteCount( - formData.aliasName, - ); - if ( - aliasLength > 0 && - isValidAliasInput && - aliasPrices !== null - ) { - // Disable alias registration if the array is not exactly one entry - if (aliasPrices.prices.length !== 1) { - setAliasValidationError( - `Alias registration is temporarily unavailable, please check again later.`, - ); - setIsValidAliasInput(false); - return; - } - // TODO Once chronik-client has been upgraded for in-node chronik, update - // this price parsing logic to use the new ws for blockheight comparisons. - // Intention is to reverse loop through `aliasPrices.prices` and parse for - // the latest array entry that has a startHeight within the chain's tipHeight. - let aliasPriceXec = toXec( - aliasPrices.prices[0].fees[ - aliasLength - ], - ).toLocaleString(); - return ( - - This {aliasLength} byte alias is - available, {aliasPriceXec} XEC - to register. - - ); - } - })()} -

- - - Register to the active wallet address - - - {!useThisAddressChecked && ( - - handleAliasAddressInput(e), - required: true, - }} - /> - )} - preparePreviewModal()} - > - Register Alias - - - - - - - - - {aliases && - aliases.registered && - aliases.registered.length > 0 - ? aliases.registered.map((alias, index) => ( - - - - {alias.alias + '.xec'} - - - - )) - : !aliasServerError && ( -

{'No registered aliases'}

- )} - - - {aliasServerError && - aliasValidationError === false && - aliasServerError} - - - - - {aliases && - aliases.pending && - aliases.pending.length > 0 - ? aliases.pending.map( - (pendingAlias, index) => ( - - - - {pendingAlias.alias + - '.xec'} - - - - ), - ) - : !aliasServerError && ( -

{'No pending aliases'}

- )} -
+ {isModalVisible && ( + + {!aliasWarningMsg && + aliasDetails && + Number.isInteger(aliasDetails.registrationFeeSats) && ( + + Register "{formData.aliasName}" for{' '} + {toXec( + aliasDetails.registrationFeeSats, + ).toLocaleString()}{' '} + XEC ? + + )} + {aliasWarningMsg !== false && + aliasDetails && + Number.isInteger(aliasDetails.registrationFeeSats) && ( - {aliasServerError && - aliasValidationError === false && - aliasServerError} + {` Warning: ${aliasWarningMsg}`} +
+
+ {` Continue the registration anyway for ${toXec( + aliasDetails.registrationFeeSats, + ).toLocaleString()} XEC?`}
-
- - -
+ )} + {!registerActiveWallet && + !aliasAddressValidationError && + ` Please also note Cashtab will only track alias registrations for ${wallet.name}: ${defaultAddress}.`} + + )} + +

eCash Namespace Alias

+ + + {(() => { + let aliasLength = getAliasByteCount(formData.aliasName); + if ( + aliasLength > 0 && + isValidAliasInput && + aliasPrices !== null + ) { + // Disable alias registration if the array is not exactly one entry + if (aliasPrices.prices.length !== 1) { + setAliasValidationError( + `Alias registration is temporarily unavailable, please check again later.`, + ); + setIsValidAliasInput(false); + return; + } + // TODO Once chronik-client has been upgraded for in-node chronik, update + // this price parsing logic to use the new ws for blockheight comparisons. + // Intention is to reverse loop through `aliasPrices.prices` and parse for + // the latest array entry that has a startHeight within the chain's tipHeight. + let aliasPriceXec = toXec( + aliasPrices.prices[0].fees[aliasLength], + ).toLocaleString(); + return ( + + This {aliasLength} byte alias is available,{' '} + {aliasPriceXec} XEC to register. + + ); + } + })()} +

+ + + setRegisterActiveWallet(!registerActiveWallet) + } + > + Register active wallet + + + {!registerActiveWallet && ( + + + + )} + preparePreviewModal()} + > + Register Alias + + + Registered Aliases + + {aliases && + aliases.registered && + aliases.registered.length > 0 + ? aliases.registered.map((alias, index) => ( + + + {alias.alias + '.xec'} + + + )) + : !aliasServerError && ( + + {'No registered aliases'} + + )} + {aliasServerError && aliasValidationError === false && ( + {aliasServerError} + )} + + Pending Aliases + + {aliases && aliases.pending && aliases.pending.length > 0 + ? aliases.pending.map((pendingAlias, index) => ( + + + {pendingAlias.alias + '.xec'} + + + )) + : !aliasServerError && ( + {'No pending aliases'} + )} + {aliasServerError && aliasValidationError === false && ( + {aliasServerError} + )} + + ); }; diff --git a/cashtab/src/components/Alias/__tests__/Alias.test.js b/cashtab/src/components/Alias/__tests__/Alias.test.js --- a/cashtab/src/components/Alias/__tests__/Alias.test.js +++ b/cashtab/src/components/Alias/__tests__/Alias.test.js @@ -112,23 +112,10 @@ expect(screen.queryByTestId('loading-ctn')).not.toBeInTheDocument(), ); - // Registered and Pending Alias dropdowns are rendered - expect( - screen.getByTestId('registered-aliases-list'), - ).toBeInTheDocument(); - expect(screen.getByTestId('pending-aliases-list')).toBeInTheDocument(); - - // Validate the aliases within the dropdowns - await waitFor(() => { - expect( - screen.getByTestId('registered-aliases-list'), - ).toHaveTextContent('chicken555.xecchicken666.xec'); - }); - await waitFor(() => { - expect( - screen.getByTestId('pending-aliases-list'), - ).toHaveTextContent('chicken444.xec'); - }); + // Validate rendering of registered and pending alias tags + expect(await screen.findByText('chicken555.xec')).toBeInTheDocument(); + expect(await screen.findByText('chicken666.xec')).toBeInTheDocument(); + expect(await screen.findByText('chicken444.xec')).toBeInTheDocument(); }); it('Registered and Pending Aliases are correctly rendered when pending list is empty', async () => { const mockedChronik = await initializeCashtabStateForTests( @@ -163,23 +150,11 @@ expect(screen.queryByTestId('loading-ctn')).not.toBeInTheDocument(), ); - // Registered and Pending Alias dropdowns are rendered + // Tags rendered as expected + expect(await screen.findByText('chicken555.xec')).toBeInTheDocument(); expect( - screen.getByTestId('registered-aliases-list'), + await screen.findByText('No pending aliases'), ).toBeInTheDocument(); - expect(screen.getByTestId('pending-aliases-list')).toBeInTheDocument(); - - // Validate the aliases within the dropdowns - await waitFor(() => { - expect( - screen.getByTestId('registered-aliases-list'), - ).toHaveTextContent('chicken555.xec'); - }); - await waitFor(() => { - expect( - screen.getByTestId('pending-aliases-list'), - ).toHaveTextContent('No pending aliases'); - }); }); it('Registered and Pending Aliases are correctly rendered when registered list is empty', async () => { const mockedChronik = await initializeCashtabStateForTests( @@ -214,23 +189,11 @@ expect(screen.queryByTestId('loading-ctn')).not.toBeInTheDocument(), ); - // Registered and Pending Alias dropdowns are rendered + // Validate the aliases within the dropdowns expect( - screen.getByTestId('registered-aliases-list'), + await screen.findByText('No registered aliases'), ).toBeInTheDocument(); - expect(screen.getByTestId('pending-aliases-list')).toBeInTheDocument(); - - // Validate the aliases within the dropdowns - await waitFor(() => { - expect( - screen.getByTestId('registered-aliases-list'), - ).toHaveTextContent('No registered aliases'); - }); - await waitFor(() => { - expect( - screen.getByTestId('pending-aliases-list'), - ).toHaveTextContent('chicken444.xec'); - }); + expect(await screen.findByText('chicken444.xec')).toBeInTheDocument(); }); it('Registered and Pending lists still renders when aliasValidationError is populated and aliasServerError is false', async () => { const mockedChronik = await initializeCashtabStateForTests( @@ -259,23 +222,12 @@ expect(screen.queryByTestId('loading-ctn')).not.toBeInTheDocument(), ); - // Registered and Pending Alias dropdowns are rendered - expect( - screen.getByTestId('registered-aliases-list'), - ).toBeInTheDocument(); - expect(screen.getByTestId('pending-aliases-list')).toBeInTheDocument(); + // We see registered aliases + expect(await screen.findByText('chicken555.xec')).toBeInTheDocument(); + expect(await screen.findByText('chicken666.xec')).toBeInTheDocument(); - // Validate the aliases within the dropdowns - await waitFor(() => { - expect( - screen.getByTestId('registered-aliases-list'), - ).toHaveTextContent('chicken555.xecchicken666.xec'); - }); - await waitFor(() => { - expect( - screen.getByTestId('pending-aliases-list'), - ).toHaveTextContent('chicken444.xec'); - }); + // We see pending alias + expect(await screen.findByText('chicken444.xec')).toBeInTheDocument(); }); it('Registered and Pending lists do not render when aliasValidationError is false and aliasServerError is populated', async () => { const mockedChronik = await initializeCashtabStateForTests( @@ -303,15 +255,7 @@ ); // Validate the aliases within the dropdowns - await waitFor(() => { - expect( - screen.getByTestId('registered-aliases-list'), - ).not.toHaveTextContent('chicken555.xec'); - }); - await waitFor(() => { - expect( - screen.getByTestId('pending-aliases-list'), - ).not.toHaveTextContent('chicken444.xec'); - }); + expect(screen.queryByText('chicken555.xec')).not.toBeInTheDocument(); + expect(screen.queryByText('chicken444.xec')).not.toBeInTheDocument(); }); }); diff --git a/cashtab/src/components/Common/CustomIcons.js b/cashtab/src/components/Common/CustomIcons.js --- a/cashtab/src/components/Common/CustomIcons.js +++ b/cashtab/src/components/Common/CustomIcons.js @@ -235,9 +235,6 @@ export const UnparsedIcon = () => ; export const HomeIcon = () => ; export const SettingsIcon = () => ; -export const PendingAliasWarningIcon = () => ( - -); export const WarningIcon = () => ; export const AirdropIcon = () => ; diff --git a/cashtab/src/components/Common/EnhancedInputs.js b/cashtab/src/components/Common/EnhancedInputs.js deleted file mode 100644 --- a/cashtab/src/components/Common/EnhancedInputs.js +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright (c) 2024 The Bitcoin developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -import * as React from 'react'; -import PropTypes from 'prop-types'; -import { Form, Input, Checkbox } from 'antd'; -import { - ThemedWalletOutlined, - ThemedAliasOutlined, -} from 'components/Common/CustomIcons'; -import styled, { css } from 'styled-components'; - -export const AntdFormCss = css` - input[type='number'] { - -moz-appearance: textfield; - } - .ant-input-group-addon { - background-color: ${props => - props.theme.forms.addonBackground} !important; - border: 1px solid ${props => props.theme.forms.border}; - color: ${props => props.theme.forms.addonForeground} !important; - } - input.ant-input, - .ant-select-selection { - background-color: ${props => - props.theme.forms.selectionBackground} !important; - box-shadow: none !important; - border-radius: 4px; - font-weight: bold; - color: ${props => props.theme.forms.text}; - opacity: 1; - height: 45px; - } - textarea.ant-input, - .ant-select-selection { - background-color: ${props => - props.theme.forms.selectionBackground} !important; - box-shadow: none !important; - border-radius: 4px; - font-weight: bold; - color: ${props => props.theme.forms.text}; - opacity: 1; - height: 50px; - min-height: 100px; - } - .ant-input-affix-wrapper { - background-color: ${props => - props.theme.forms.selectionBackground} !important; - border: 1px solid ${props => props.theme.forms.border} !important; - } - .ant-input-wrapper .anticon-qrcode { - color: ${props => props.theme.forms.addonForeground} !important; - } - input.ant-input::placeholder, - .ant-select-selection::placeholder { - color: ${props => props.theme.forms.placeholder} !important; - } - .ant-select-selector { - height: 55px !important; - border: 1px solid ${props => props.theme.forms.border} !important; - background-color: ${props => - props.theme.forms.selectionBackground}!important; - } - .ant-form-item-has-error - > div - > div.ant-form-item-control-input - > div - > span - > span - > span.ant-input-affix-wrapper { - background-color: ${props => props.theme.forms.selectionBackground}; - border-color: ${props => props.theme.forms.error} !important; - } - .ant-form-item-control-input-content { - color: ${props => props.theme.forms.text} !important; - } - .ant-input:hover { - border-color: ${props => props.theme.forms.highlightBox}; - } - - .ant-form-item-has-error .ant-input, - .ant-form-item-has-error .ant-input-affix-wrapper, - .ant-form-item-has-error .ant-input:hover, - .ant-form-item-has-error .ant-input-affix-wrapper:hover { - background-color: ${props => props.theme.forms.selectionBackground}; - border-color: ${props => props.theme.forms.error} !important; - } - - .ant-form-item-has-error - .ant-select:not(.ant-select-disabled):not(.ant-select-customize-input) - .ant-select-selector { - background-color: ${props => props.theme.forms.selectionBackground}; - border-color: ${props => props.theme.forms.error} !important; - } - .ant-select-single .ant-select-selector .ant-select-selection-item, - .ant-select-single .ant-select-selector .ant-select-selection-placeholder { - line-height: 55px; - text-align: left; - color: ${props => props.theme.forms.text}; - font-weight: bold; - } - .ant-form-item-has-error .ant-input-group-addon { - color: ${props => props.theme.forms.error} !important; - border-color: ${props => props.theme.forms.error} !important; - } - .ant-form-item-explain .ant-form-item-explain-error { - color: ${props => props.theme.forms.error} !important; - overflow: hidden; - text-overflow: ellipsis; - width: 100%; - min-width: 1px; - font-size: 12px; - } - .ant-input-suffix { - color: ${props => props.theme.lightWhite}; - } -`; - -export const AntdFormWrapper = styled.div` - ${AntdFormCss} -`; - -export const CashtabCheckbox = styled(Checkbox)` - .ant-checkbox-checked .ant-checkbox-inner { - background-color: ${props => props.theme.eCashBlue} !important; - border-color: ${props => props.theme.eCashBlue} !important; - } - .ant-checkbox + span { - color: ${props => props.theme.forms.text} !important; - } -`; - -export const AliasInput = ({ inputProps, ...otherProps }) => { - return ( - - - } - autoComplete="off" - {...inputProps} - /> - - - ); -}; - -AliasInput.propTypes = { - inputProps: PropTypes.object, -}; - -export const AliasAddressInput = ({ inputProps, ...otherProps }) => { - return ( - - - } - autoComplete="off" - {...inputProps} - /> - - - ); -}; - -AliasAddressInput.propTypes = { - inputProps: PropTypes.object, -}; diff --git a/cashtab/src/components/Common/Inputs.js b/cashtab/src/components/Common/Inputs.js --- a/cashtab/src/components/Common/Inputs.js +++ b/cashtab/src/components/Common/Inputs.js @@ -107,6 +107,10 @@ min-width: 59px; `; +const AliasSuffixHolder = styled(OnMaxBtn)` + cursor: auto; +`; + const CurrencyDropdown = styled.select` cursor: ${props => (props.disabled ? 'not-allowed' : 'pointer')}; font-size: 18px; @@ -424,6 +428,43 @@ handleOnMax: PropTypes.func, }; +export const AliasInput = ({ + name = '', + placeholder = '', + value = '', + inputDisabled = false, + error = false, + handleInput, +}) => { + return ( + + + handleInput(e)} + disabled={inputDisabled} + /> + .xec + + {typeof error === 'string' ? error : ''} + + ); +}; + +AliasInput.propTypes = { + name: PropTypes.string, + placeholder: PropTypes.string, + value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + decimals: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + inputDisabled: PropTypes.bool, + error: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), + handleInput: PropTypes.func, + handleOnMax: PropTypes.func, +}; + const CashtabSlider = styled.input` width: 100%; `; diff --git a/cashtab/src/components/Common/StyledCollapse.js b/cashtab/src/components/Common/StyledCollapse.js deleted file mode 100644 --- a/cashtab/src/components/Common/StyledCollapse.js +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) 2024 The Bitcoin developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -import React from 'react'; -import styled from 'styled-components'; -import { Collapse } from 'antd'; -import PropTypes from 'prop-types'; - -const { Panel } = Collapse; - -export const StyledCollapse = styled(Collapse)` - background: ${props => props.theme.collapses.background} !important; - border: 1px solid ${props => props.theme.collapses.border} !important; - - .ant-collapse-content { - border-top: none; - background-color: ${props => - props.theme.collapses.expandedBackground} !important; - } - - .ant-collapse-item { - border-bottom: none !important; - } - - *:not(button) { - color: ${props => props.theme.collapses.color} !important; - } -`; -const CenteredTitleCollapse = styled.div``; - -const CollapseCtn = styled.div` - .ant-collapse-header { - .anticon { - flex: 1; - } - ${CenteredTitleCollapse} { - flex: 2; - } - } - .ant-form-small { - color: ${props => props.theme.lightGrey} !important; - } -`; - -export const TokenCollapse = styled(Collapse)` - ${({ disabled = false, ...props }) => - disabled === true - ? ` - background: ${props.theme.buttons.secondary.background} !important; - .ant-collapse-header { - font-size: 18px; - font-weight: bold; - color: ${props.theme.buttons.secondary.color} !important; - svg { - color: ${props.theme.buttons.secondary.color} !important; - } - } - .ant-collapse-arrow { - font-size: 18px; - } - ` - : ` - background: ${props.theme.eCashBlue} !important; - .ant-collapse-header { - font-size: 18px; - font-weight: bold; - color: ${props.theme.contrast} !important; - svg { - color: ${props.theme.contrast} !important; - } - } - .ant-collapse-arrow { - font-size: 18px; - } - `} -`; - -export const AdvancedCollapse = styled(Collapse)` - .ant-input-textarea-show-count:after { - color: ${props => props.theme.lightGrey} !important; - } - .ant-collapse-content { - background-color: ${props => - props.theme.advancedCollapse.expandedBackground} !important; - } - ${({ disabled = false, ...props }) => - disabled === true - ? ` - background: ${props.theme.buttons.secondary.background} !important; - .ant-collapse-header { - font-size: 18px; - font-weight: normal; - color: ${props.theme.buttons.secondary.color} !important; - svg { - color: ${props.theme.buttons.secondary.color} !important; - } - } - .ant-collapse-arrow { - font-size: 18px; - } - ` - : ` - background: ${props.theme.advancedCollapse.background} !important; - .ant-collapse-header { - font-size: 18px; - font-weight: bold; - color: ${props.theme.advancedCollapse.color} !important; - svg { - color: ${props.theme.advancedCollapse.icon} !important; - } - } - .ant-collapse-arrow { - font-size: 18px; - } - - `} -`; - -export const CustomCollapseCtn = ({ - panelHeader, - children, - optionalDefaultActiveKey, - optionalKey, -}) => { - return ( - - - - {panelHeader} - - } - key={optionalKey} - > - {children} - - - - ); -}; - -CustomCollapseCtn.propTypes = { - optionalDefaultActiveKey: PropTypes.arrayOf(PropTypes.string), - panelHeader: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), - children: PropTypes.node, - optionalKey: PropTypes.string, -}; diff --git a/cashtab/src/wallet/useWallet.js b/cashtab/src/wallet/useWallet.js --- a/cashtab/src/wallet/useWallet.js +++ b/cashtab/src/wallet/useWallet.js @@ -951,7 +951,9 @@ // 3) No interval is set to watch these pending aliases // 4) We have an active wallet // Set an interval to watch these pending aliases - refreshAliasesOnStartup(cashtabState.wallets[0].paths.get(1899)); + refreshAliasesOnStartup( + cashtabState.wallets[0].paths.get(1899).address, + ); } else if (aliases?.pending?.length === 0 && aliasIntervalId !== null) { // If we have no pending aliases but we still have an interval to check them, clearInterval clearInterval(aliasIntervalId);