sforkowany z mirror/soapbox
SoapboxConfig: use Streamfield for cryptoAddresses
rodzic
9bd18b13bd
commit
2588bdd4ff
|
@ -6,7 +6,8 @@ import { updateConfig } from 'soapbox/actions/admin';
|
||||||
import { uploadMedia } from 'soapbox/actions/media';
|
import { uploadMedia } from 'soapbox/actions/media';
|
||||||
import snackbar from 'soapbox/actions/snackbar';
|
import snackbar from 'soapbox/actions/snackbar';
|
||||||
import Icon from 'soapbox/components/icon';
|
import Icon from 'soapbox/components/icon';
|
||||||
import { Column } from 'soapbox/components/ui';
|
import { Column, HStack, Input } from 'soapbox/components/ui';
|
||||||
|
import Streamfield, { StreamfieldComponent } from 'soapbox/components/ui/streamfield/streamfield';
|
||||||
import {
|
import {
|
||||||
SimpleForm,
|
SimpleForm,
|
||||||
FieldsGroup,
|
FieldsGroup,
|
||||||
|
@ -27,6 +28,7 @@ import IconPicker from './components/icon-picker';
|
||||||
import SitePreview from './components/site-preview';
|
import SitePreview from './components/site-preview';
|
||||||
|
|
||||||
import type { ColorChangeHandler, ColorResult } from 'react-color';
|
import type { ColorChangeHandler, ColorResult } from 'react-color';
|
||||||
|
import type { CryptoAddress } from 'soapbox/types/soapbox';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
heading: { id: 'column.soapbox_config', defaultMessage: 'Soapbox config' },
|
heading: { id: 'column.soapbox_config', defaultMessage: 'Soapbox config' },
|
||||||
|
@ -67,6 +69,42 @@ const templates: Record<string, Template> = {
|
||||||
cryptoAddress: ImmutableMap({ ticker: '', address: '', note: '' }),
|
cryptoAddress: ImmutableMap({ ticker: '', address: '', note: '' }),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const CryptoAddressInput: StreamfieldComponent<CryptoAddress> = ({ value, onChange }) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const handleChange = (key: 'ticker' | 'address' | 'note'): React.ChangeEventHandler<HTMLInputElement> => {
|
||||||
|
return e => {
|
||||||
|
onChange(value.set(key, e.currentTarget.value));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<HStack space={2} grow>
|
||||||
|
<Input
|
||||||
|
type='text'
|
||||||
|
outerClassName='w-1/6 flex-grow'
|
||||||
|
value={value.ticker}
|
||||||
|
onChange={handleChange('ticker')}
|
||||||
|
placeholder={intl.formatMessage(messages.cryptoAdressItemTicker)}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
type='text'
|
||||||
|
outerClassName='w-3/6 flex-grow'
|
||||||
|
value={value.address}
|
||||||
|
onChange={handleChange('address')}
|
||||||
|
placeholder={intl.formatMessage(messages.cryptoAdressItemAddress)}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
type='text'
|
||||||
|
outerClassName='w-2/6 flex-grow'
|
||||||
|
value={value.note}
|
||||||
|
onChange={handleChange('note')}
|
||||||
|
placeholder={intl.formatMessage(messages.cryptoAdressItemNote)}
|
||||||
|
/>
|
||||||
|
</HStack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const SoapboxConfig: React.FC = () => {
|
const SoapboxConfig: React.FC = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
@ -187,10 +225,18 @@ const SoapboxConfig: React.FC = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCryptoAdressItemChange = (index: number, key: string, field: any, getValue?: ValueGetter) => {
|
const handleCryptoAdressChange = (values: CryptoAddress[]) => {
|
||||||
return handleItemChange(
|
setConfig(['cryptoAddresses'], ImmutableList(values));
|
||||||
['cryptoAddresses', index], key, field, templates.cryptoAddress, getValue,
|
};
|
||||||
);
|
|
||||||
|
const addCryptoAddress = () => {
|
||||||
|
const cryptoAddresses = data.get('cryptoAddresses');
|
||||||
|
setConfig(['cryptoAddresses'], cryptoAddresses.push(templates.cryptoAddress));
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeCryptoAddress = (i: number) => {
|
||||||
|
const cryptoAddresses = data.get('cryptoAddresses');
|
||||||
|
setConfig(['cryptoAddresses'], cryptoAddresses.delete(i));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEditJSON: React.ChangeEventHandler<HTMLTextAreaElement> = e => {
|
const handleEditJSON: React.ChangeEventHandler<HTMLTextAreaElement> = e => {
|
||||||
|
@ -385,45 +431,17 @@ const SoapboxConfig: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</FieldsGroup>
|
</FieldsGroup>
|
||||||
<FieldsGroup>
|
|
||||||
<div className='input with_block_label'>
|
<Streamfield
|
||||||
<label><FormattedMessage id='soapbox_config.fields.crypto_addresses_label' defaultMessage='Cryptocurrency addresses' /></label>
|
label={<FormattedMessage id='soapbox_config.fields.crypto_addresses_label' defaultMessage='Cryptocurrency addresses' />}
|
||||||
<span className='hint'>
|
hint={<FormattedMessage id='soapbox_config.hints.crypto_addresses' defaultMessage='Add cryptocurrency addresses so users of your site can donate to you. Order matters, and you must use lowercase ticker values.' />}
|
||||||
<FormattedMessage id='soapbox_config.hints.crypto_addresses' defaultMessage='Add cryptocurrency addresses so users of your site can donate to you. Order matters, and you must use lowercase ticker values.' />
|
component={CryptoAddressInput}
|
||||||
</span>
|
values={soapbox.cryptoAddresses.toArray()}
|
||||||
{
|
onChange={handleCryptoAdressChange}
|
||||||
soapbox.cryptoAddresses.map((address, i) => (
|
onAddItem={addCryptoAddress}
|
||||||
<div className='row' key={i}>
|
onRemoveItem={removeCryptoAddress}
|
||||||
<TextInput
|
|
||||||
label={intl.formatMessage(messages.cryptoAdressItemTicker)}
|
|
||||||
placeholder={intl.formatMessage(messages.cryptoAdressItemTicker)}
|
|
||||||
value={address.ticker}
|
|
||||||
onChange={handleCryptoAdressItemChange(i, 'ticker', address)}
|
|
||||||
/>
|
/>
|
||||||
<TextInput
|
|
||||||
label={intl.formatMessage(messages.cryptoAdressItemAddress)}
|
|
||||||
placeholder={intl.formatMessage(messages.cryptoAdressItemAddress)}
|
|
||||||
value={address.address}
|
|
||||||
onChange={handleCryptoAdressItemChange(i, 'address', address)}
|
|
||||||
/>
|
|
||||||
<TextInput
|
|
||||||
label={intl.formatMessage(messages.cryptoAdressItemNote)}
|
|
||||||
placeholder={intl.formatMessage(messages.cryptoAdressItemNote)}
|
|
||||||
value={address.note}
|
|
||||||
onChange={handleCryptoAdressItemChange(i, 'note', address)}
|
|
||||||
/>
|
|
||||||
<Icon className='delete-field' src={require('@tabler/icons/icons/circle-x.svg')} onClick={handleDeleteItem(['cryptoAddresses', i])} />
|
|
||||||
</div>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
<div className='actions add-row'>
|
|
||||||
<div role='presentation' className='btn button button-secondary' onClick={handleAddItem(['cryptoAddresses'], templates.cryptoAddress)}>
|
|
||||||
<Icon src={require('@tabler/icons/icons/circle-plus.svg')} />
|
|
||||||
<FormattedMessage id='soapbox_config.fields.crypto_address.add' defaultMessage='Add new crypto address' />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</FieldsGroup>
|
|
||||||
<FieldsGroup>
|
<FieldsGroup>
|
||||||
<SimpleInput
|
<SimpleInput
|
||||||
type='number'
|
type='number'
|
||||||
|
|
Ładowanie…
Reference in New Issue