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);