Added branding_preview. Edited index

merge-requests/107/merge
crockwave 4 years ago
parent 2af5149ed3
commit eef32c96e3

@ -0,0 +1,32 @@
import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { acctFull } from 'soapbox/utils/accounts';
import StillImage from 'soapbox/components/still_image';
const BrandingPreview = ({ account }) => (
<div className='card h-card'>
<a target='_blank' rel='noopener' href={account.get('url')}>
<div className='card__img'>
<StillImage alt='' src={account.get('header')} />
</div>
<div className='card__bar'>
<div className='avatar'>
<StillImage alt='' className='u-photo' src={account.get('avatar')} width='48' height='48' />
</div>
<div className='display-name'>
<span style={{ display: 'none' }}>{account.get('username')}</span>
<bdi>
<strong className='emojify p-name'>{account.get('display_name')}</strong>
</bdi>
<span>{acctFull(account)}</span>
</div>
</div>
</a>
</div>
);
BrandingPreview.propTypes = {
account: ImmutablePropTypes.map,
};
export default BrandingPreview;

@ -12,6 +12,7 @@ import {
Checkbox,
FileChooser,
} from 'soapbox/features/forms';
import BrandingPreview from './components/branding_preview';
import {
Map as ImmutableMap,
List as ImmutableList,
@ -19,82 +20,37 @@ import {
import { patchMe } from 'soapbox/actions/me';
import { unescape } from 'lodash';
const MAX_FIELDS = 6; // Max promoPanel fields
const messages = defineMessages({
heading: { id: 'column.edit_profile', defaultMessage: 'Edit profile' },
metaFieldLabel: { id: 'edit_profile.fields.meta_fields.label_placeholder', defaultMessage: 'Label' },
metaFieldContent: { id: 'edit_profile.fields.meta_fields.content_placeholder', defaultMessage: 'Content' },
heading: { id: 'column.soapbox_settings', defaultMessage: 'Soapbox settings' },
promoPanelIcon: { id: 'soapbox_settings.promo_panel.meta_fields.icon_placeholder', defaultMessage: 'Icon' },
promoPanelLabel: { id: 'soapbox_settings.promo_panel.meta_fields.label_placeholder', defaultMessage: 'Label' },
promoPanelURL: { id: 'soapbox_settings.promo_panel.meta_fields.url_placeholder', defaultMessage: 'URL' },
homeFooterLabel: { id: 'soapbox_settings.home_footer.meta_fields.label_placeholder', defaultMessage: 'Label' },
homeFooterURL: { id: 'soapbox_settings.home_footer.meta_fields.url_placeholder', defaultMessage: 'URL' },
});
const mapStateToProps = state => {
const soapbox = state.get('soapbox');
return {
themeCss: generateThemeCss(state.getIn(['soapbox', 'brandColor'])),
customCss: state.getIn(['soapbox', 'customCss']),
logo: state.getIn(['soapbox', 'logo']),
logo: state.getIn(['soapbox', 'logo']),
promoPanel: state.getIn(['soapbox', 'promoPanel', 'items']),
patronEnabled: state.getIn(['soapbox', 'extensions', 'patron', 'enabled']),
displayMode: state.getIn(['soapbox', 'defaultSettings', 'mode']),
autoPlayGif: state.getIn(['soapbox', 'defaultSettings', 'autoPlayGif']),
copyright: state.getIn(['soapbox', 'copyright']),
homeFooter: state.getIn(['soapbox', 'navLinks', 'homeFooter']),
// {
// soapbox: {
// brandColor: '#1ca82b',
// logo: '/favicon.png',
// promoPanel: {
// items: [
// {
// icon: 'area-chart',
// text: 'Gleasonator stats',
// url: 'https://fediverse.network/gleasonator.com'
// },
// {
// icon: 'comment-o',
// text: 'Gleasonator theme song',
// url: 'https://media.gleasonator.com/custom/261905_gleasonator_song.mp3'
// }
// ]
// },
// extensions: {
// patron: {
// enabled: true
// }
// },
// defaultSettings: {
// mode: 'light'
// },
// copyright: '♡2020. Copying is an act of love. Please copy and share.',
// navlinks: {
// homeFooter: [
// {
// title: 'About',
// url: '/about'
// },
// {
// title: 'Terms of Service',
// url: '/about/tos'
// },
// {
// title: 'Privacy Policy',
// url: '/about/privacy'
// },
// {
// title: 'DMCA',
// url: '/about/dmca'
// },
// {
// title: 'Source Code',
// url: '/about#opensource'
// }
// ]
// }
// }
// }
};
};
// Forces fields to be MAX_SIZE, filling empty values
const normalizeFields = fields => (
ImmutableList(fields).setSize(MAX_FIELDS).map(field =>
field ? field : ImmutableMap({ name: '', value: '' })
)
);
// HTML unescape for special chars, eg <br>
const unescapeParams = (map, params) => (
params.reduce((map, param) => (
@ -109,26 +65,31 @@ class ConfigSoapbox extends ImmutablePureComponent {
static propTypes = {
dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
account: ImmutablePropTypes.map,
themeCss: PropTypes.text,
logo: PropTypes.object,
promoPanel: ImmutablePropTypes.map,
patronEnabled: PropTypes.Boolean,
autoPlayGif: PropTypes.Boolean,
copyright: PropTypes.text,
homeFooter: ImmutablePropTypes.map,
};
state = {
isLoading: false,
fields: normalizeFields(Array.from({ length: MAX_FIELDS })),
promoPanel: normalizeFields(Array.from({ length: MAX_FIELDS })),
}
constructor(props) {
super(props);
const initialState = props.account.withMutations(map => {
const initialState = props.withMutations(map => {
map.merge(map.get('source'));
map.delete('source');
map.set('fields', normalizeFields(map.get('fields')));
unescapeParams(map, ['display_name', 'note']);
map.set('promoPanel', normalizeFields(map.get('promoPanel')));
});
this.state = initialState.toObject();
}
makePreviewAccount = () => {
makePreviewLogo = () => {
const { account } = this.props;
return account.merge(ImmutableMap({
header: this.state.header,
@ -137,12 +98,12 @@ class ConfigSoapbox extends ImmutablePureComponent {
}));
}
getFieldParams = () => {
getPromoPanelParams = () => {
let params = ImmutableMap();
this.state.fields.forEach((f, i) =>
this.state.promoPanel.forEach((f, i) =>
params = params
.set(`fields_attributes[${i}][name]`, f.get('name'))
.set(`fields_attributes[${i}][value]`, f.get('value'))
.set(`promo_panel_attributes[${i}][name]`, f.get('name'))
.set(`promo_panel_attributes[${i}][value]`, f.get('value'))
);
return params;
}
@ -150,21 +111,20 @@ class ConfigSoapbox extends ImmutablePureComponent {
getParams = () => {
const { state } = this;
return Object.assign({
discoverable: state.discoverable,
bot: state.bot,
display_name: state.display_name,
note: state.note,
avatar: state.avatar_file,
header: state.header_file,
locked: state.locked,
}, this.getFieldParams().toJS());
themeCss: state.themeCss,
logoFile: state.logoFile,
patronEnabled: state.patronEnabled,
displayMode: state.displayMode,
copyright: state.copyright,
homeFooter: state.homeFooter,
}, this.getPromoPanelParams().toJS());
}
getFormdata = () => {
const data = this.getParams();
let formData = new FormData();
for (let key in data) {
const shouldAppend = Boolean(data[key] || key.startsWith('fields_attributes'));
const shouldAppend = Boolean(data[key] || key.startsWith('promo_panel_attributes'));
if (shouldAppend) formData.append(key, data[key] || '');
}
return formData;
@ -189,7 +149,7 @@ class ConfigSoapbox extends ImmutablePureComponent {
this.setState({ [e.target.name]: e.target.value });
}
handleFieldChange = (i, key) => {
handlePromoPanelChange = (i, key) => {
return (e) => {
this.setState({
fields: this.state.fields.setIn([i, key], e.target.value),
@ -212,7 +172,7 @@ class ConfigSoapbox extends ImmutablePureComponent {
const { intl } = this.props;
return (
<Column icon='user' heading={intl.formatMessage(messages.heading)} backBtnSlim>
<Column icon='gears' heading={intl.formatMessage(messages.heading)} backBtnSlim>
<SimpleForm onSubmit={this.handleSubmit}>
<fieldset disabled={this.state.isLoading}>
<FieldsGroup>
@ -230,7 +190,7 @@ class ConfigSoapbox extends ImmutablePureComponent {
/>
<div className='fields-row'>
<div className='fields-row__column fields-row__column-6'>
<ProfilePreview account={this.makePreviewAccount()} />
<ProfilePreview account={this.makePreviewLogo()} />
</div>
<div className='fields-row__column fields-group fields-row__column-6'>
<FileChooser
@ -275,12 +235,12 @@ class ConfigSoapbox extends ImmutablePureComponent {
<TextInput
placeholder={intl.formatMessage(messages.metaFieldLabel)}
value={field.get('name')}
onChange={this.handleFieldChange(i, 'name')}
onChange={this.handlePromoPanelChange(i, 'name')}
/>
<TextInput
placeholder={intl.formatMessage(messages.metaFieldContent)}
value={field.get('value')}
onChange={this.handleFieldChange(i, 'value')}
onChange={this.handlePromoPanelChange(i, 'value')}
/>
</div>
))

@ -71,6 +71,7 @@ import {
LoginPage,
Preferences,
EditProfile,
ConfigSoapbox,
PasswordReset,
SecurityForm,
} from './util/async-components';
@ -253,6 +254,7 @@ class SwitchingColumnsArea extends React.PureComponent {
<Redirect exact from='/settings' to='/settings/preferences' />
<WrappedRoute path='/settings/preferences' layout={LAYOUT.DEFAULT} component={Preferences} content={children} />
<WrappedRoute path='/settings/profile' layout={LAYOUT.DEFAULT} component={EditProfile} content={children} />
<WrappedRoute path='/admin' layout={LAYOUT.DEFAULT} component={ConfigSoapbox} content={children} />
<WrappedRoute layout={LAYOUT.EMPTY} component={GenericNotFound} content={children} />
</Switch>

@ -178,6 +178,10 @@ export function EditProfile() {
return import(/* webpackChunkName: "features/edit_profile" */'../../edit_profile');
}
export function ConfigSoapbox() {
return import(/* webpackChunkName: "features/configuration" */'../../configuration');
}
export function PasswordReset() {
return import(/* webpackChunkName: "features/auth_login" */'../../auth_login/components/password_reset');
}

Loading…
Cancel
Save