diff --git a/app/soapbox/actions/soapbox.js b/app/soapbox/actions/soapbox.js index e729a3da2..eedd1787f 100644 --- a/app/soapbox/actions/soapbox.js +++ b/app/soapbox/actions/soapbox.js @@ -4,7 +4,7 @@ import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; export const SOAPBOX_CONFIG_REQUEST_SUCCESS = 'SOAPBOX_CONFIG_REQUEST_SUCCESS'; export const SOAPBOX_CONFIG_REQUEST_FAIL = 'SOAPBOX_CONFIG_REQUEST_FAIL'; -const defaultConfig = ImmutableMap({ +export const defaultConfig = ImmutableMap({ logo: '', banner: '', brandColor: '#0482d8', // Azure diff --git a/app/soapbox/features/soapbox_config/index.js b/app/soapbox/features/soapbox_config/index.js index 5bb6817c2..30c3e958d 100644 --- a/app/soapbox/features/soapbox_config/index.js +++ b/app/soapbox/features/soapbox_config/index.js @@ -14,15 +14,10 @@ import { ColorWithPicker, FileChooserLogo, } from 'soapbox/features/forms'; -import StillImage from 'soapbox/components/still_image'; -import { - Map as ImmutableMap, - List as ImmutableList, - getIn, -} from 'immutable'; +import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; import { updateAdminConfig } from 'soapbox/actions/admin'; import Icon from 'soapbox/components/icon'; -import { getSoapboxConfig } from 'soapbox/actions/soapbox'; +import { defaultConfig } from 'soapbox/actions/soapbox'; const messages = defineMessages({ heading: { id: 'column.soapbox_config', defaultMessage: 'Soapbox config' }, @@ -35,8 +30,13 @@ const messages = defineMessages({ customCssLabel: { id: 'soapbox_config.custom_css.meta_fields.url_placeholder', defaultMessage: 'URL' }, }); +const templates = { + promoPanelItem: ImmutableMap({ icon: '', text: '', url: '' }), + footerItem: ImmutableMap({ title: '', url: '' }), +}; + const mapStateToProps = state => ({ - soapbox: getSoapboxConfig(state), + soapbox: state.get('soapbox'), }); export default @connect(mapStateToProps) @@ -44,103 +44,33 @@ export default @connect(mapStateToProps) class SoapboxConfig extends ImmutablePureComponent { static propTypes = { - soapbox: ImmutablePropTypes.map, + soapbox: ImmutablePropTypes.map.isRequired, dispatch: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, }; state = { isLoading: false, + soapbox: this.props.soapbox, } - constructor(props) { - super(props); - var promoPanelItems = getIn(this.props.soapbox, ['promoPanel'], ['items'], []).get('items'); - if (promoPanelItems.size === 0) { - this.state.promoPanelItems = ImmutableList([ - ImmutableMap({ - icon: '', - text: '', - url: '', - }), - ]); - } else { - this.state.promoPanelItems = promoPanelItems; - }; - var homeFooterItems = getIn(this.props.soapbox, ['navlinks'], ['homefooter'], []).get('homeFooter'); - if (homeFooterItems.size === 0) { - this.state.homeFooterItems = ImmutableList([ - ImmutableMap({ - title: '', - url: '', - }), - ]); - } else { - this.state.homeFooterItems = homeFooterItems; - }; - var customCssItems = getIn(this.props.soapbox, ['customCss'], []); - if (customCssItems.size === 0) { - this.state.customCssItems = ImmutableList(['']); - } else { - this.state.customCssItems = customCssItems; - }; - this.state.patron = getIn(this.props.soapbox, ['extensions', 'patron'], false); - this.state.autoPlayGif = getIn(this.props.soapbox, ['defaultSettings', 'autoPlayGif'], false); - this.handlecustomCSSChange = this.handleCustomCSSChange.bind(this); - this.handleAutoPlayGifCheckboxChange = this.handleAutoPlayGifCheckboxChange.bind(this); - this.handlePatronCheckboxChange = this.handlePatronCheckboxChange.bind(this); - } + setConfig = (path, value) => { + const { soapbox } = this.state; + const config = soapbox.setIn(path, value); + this.setState({ soapbox: config }); + }; getParams = () => { - const { state } = this; - var obj = { + const { soapbox } = this.state; + return { configs: [{ group: ':pleroma', key: ':frontend_configurations', value: [{ - tuple: [':soapbox_fe', - { - logo: '', - banner: '', - brandColor: '', - customCss: [], - promoPanel: { - items: [], - }, - extensions: { - patron: false, - }, - defaultSettings: { - autoPlayGif: false, - }, - copyright: '', - navlinks: { - homeFooter: [], - }, - }, - ], + tuple: [':soapbox_fe', soapbox.toJSON()], }], }], }; - obj.configs[0].value[0].tuple[1].logo = (state.logo ? state.logo : getIn(this.props.soapbox, ['logo'], '')); - obj.configs[0].value[0].tuple[1].banner = (state.banner ? state.banner : getIn(this.props.soapbox, ['banner'], '')); - obj.configs[0].value[0].tuple[1].brandColor = (state.brandColor ? state.brandColor : getIn(this.props.soapbox, ['brandColor'], '')); - obj.configs[0].value[0].tuple[1].extensions.patron = (state.patron !== undefined ? state.patron : getIn(this.props.soapbox, ['extensions', 'patron'], false)); - obj.configs[0].value[0].tuple[1].defaultSettings.autoPlayGif = (state.autoPlayGif !== undefined ? state.autoPlayGif : getIn(this.props.soapbox, ['defaultSettings', 'autoPlayGif'], false)); - obj.configs[0].value[0].tuple[1].copyright = (state.copyright ? state.copyright : getIn(this.props.soapbox, ['copyright'], '')); - var homeFooterItems = (state.homeFooterItems ? state.homeFooterItems : getIn(this.props.soapbox, ['navlinks'], ['homeFooter'], [])); - homeFooterItems.forEach((f) => - obj.configs[0].value[0].tuple[1].navlinks.homeFooter.push({ title: f.get('title'), url: f.get('url') }) - ); - var promoPanelItems = (state.promoPanelItems ? state.promoPanelItems : getIn(this.props.soapbox, ['promoPanel'], ['items'], [])); - promoPanelItems.forEach((f) => - obj.configs[0].value[0].tuple[1].promoPanel.items.push({ icon: f.get('icon'), text: f.get('text'), url: f.get('url') }) - ); - var customCssItems = (state.customCssItems ? state.customCssItems : getIn(this.props.soapbox, ['customCss'], [])); - customCssItems.forEach((f) => - obj.configs[0].value[0].tuple[1].customCss.push(f) - ); - return obj; } handleSubmit = (event) => { @@ -154,102 +84,55 @@ class SoapboxConfig extends ImmutablePureComponent { event.preventDefault(); } - handlePatronCheckboxChange = e => { - this.setState({ patron: !this.state.patron }); - } - - handleAutoPlayGifCheckboxChange = e => { - this.setState({ autoPlayGif: !this.state.autoPlayGif }); - } - - handleBrandColorChange = e => { - this.setState({ - brandColor: e.hex, - }); - } - - handleTextChange = e => { - this.setState({ - [e.target.name]: e.target.value, - }); - } - - handlePromoItemsChange = (i, key) => { - return (e) => { - this.setState({ - promoPanelItems: this.state.promoPanelItems.setIn([i, key], e.target.value), - }); + handleChange = (path, getValue) => { + return e => { + this.setConfig(path, getValue(e)); }; - } + }; - handleHomeFooterItemsChange = (i, key) => { - return (e) => { - this.setState({ - homeFooterItems: this.state.homeFooterItems.setIn([i, key], e.target.value), - }); + handleAddItem = (path, template) => { + return e => { + this.setConfig( + path, + this.getSoapboxConfig().getIn(path, ImmutableList()).push(template), + ); }; + }; + + handleItemChange = (path, key, field, template) => { + return this.handleChange( + path, (e) => + template + .merge(field) + .set(key, e.target.value) + ); + }; + + handlePromoItemChange = (index, key, field) => { + return this.handleItemChange( + ['promoPanel', 'items', index], key, field, templates.promoPanelItem + ); + }; + + handleHomeFooterItemChange = (index, key, field) => { + return this.handleItemChange( + ['navlinks', 'homeFooter', index], key, field, templates.footerItem + ); + }; + + getSoapboxConfig = () => { + return defaultConfig.mergeDeep(this.state.soapbox); } - handleCustomCSSChange = i => { - return (e) => { - this.setState({ - customCssItems: this.state.customCssItems.setIn([i], e.target.value), - }); - }; - } - - handleFileChange = e => { - const { name } = e.target; - const [file] = e.target.files || []; - const url = file ? URL.createObjectURL(file) : this.state[name]; - - this.setState({ - [name]: url, - [`${name}_file`]: file, - }); - } - - handleAddPromoPanelItem = () => { - - this.setState({ - promoPanelItems: this.state.promoPanelItems.concat([ - ImmutableMap({ - icon: '', - text: '', - url: '', - }), - ]), - }); - } - - handleAddHomeFooterItem = () => { - this.setState({ - homeFooterItems: this.state.homeFooterItems.concat([ - ImmutableMap({ - title: '', - url: '', - }), - ]), - }); - } - - handleAddCssItem = () => { - this.setState({ - customCssItems: this.state.customCssItems.concat(['']), - }); + componentDidUpdate(prevProps, prevState) { + if (prevProps.soapbox !== this.props.soapbox) { + this.setState({ soapbox: this.props.soapbox }); + } } render() { const { intl } = this.props; - const logo = (this.state.logo ? this.state.logo : getIn(this.props.soapbox, ['logo'], '')); - const banner = (this.state.banner ? this.state.banner : getIn(this.props.soapbox, ['banner'], '')); - const brandColor = (this.state.brandColor ? this.state.brandColor : getIn(this.props.soapbox, ['brandColor'], '')); - const patron = (this.state.patron !== undefined ? this.state.patron : getIn(this.props.soapbox, ['extensions', 'patron'], false)); - const autoPlayGif = (this.state.autoPlayGif !== undefined ? this.state.autoPlayGif : getIn(this.props.soapbox, ['defaultSettings', 'autoPlayGif'], false)); - const promoPanelItems = (this.state.promoPanelItems ? this.state.promoPanelItems : getIn(this.props.soapbox, ['promoPanel'], ['items'], []).get('items')); - const homeFooterItems = (this.state.homeFooterItems ? this.state.homeFooterItems : getIn(this.props.soapbox, ['navlinks'], ['homeFooter'], []).get('homeFooter')); - const customCssItems = (this.state.customCssItems ? this.state.customCssItems : getIn(this.props.soapbox, ['customCss'], [])); - const copyright = (this.state.copyright ? this.state.copyright : getIn(this.props.soapbox, ['copyright'], '')); + const soapbox = this.getSoapboxConfig(); return ( @@ -258,27 +141,27 @@ class SoapboxConfig extends ImmutablePureComponent {
- +
} name='logo' hint={
- {this.state.banner ? () : ()} +
} name='banner' hint={} - onChange={this.handleFileChange} + // onChange={this.handleFileChange} />
@@ -288,8 +171,8 @@ class SoapboxConfig extends ImmutablePureComponent { } - value={brandColor} - onChange={this.handleBrandColorChange} + value={soapbox.get('brandColor')} + onChange={this.handleChange(['brandColor'], (e) => e.hex)} />
@@ -298,15 +181,10 @@ class SoapboxConfig extends ImmutablePureComponent { label={} hint={} name='patron' - checked={patron} - onChange={this.handlePatronCheckboxChange} - /> - } - hint={} - name='autoPlayGif' - checked={autoPlayGif} - onChange={this.handleAutoPlayGifCheckboxChange} + checked={soapbox.getIn(['extensions', 'patron', 'enabled'])} + onChange={this.handleChange( + ['extensions', 'patron', 'enabled'], (e) => e.checked, + )} /> @@ -314,8 +192,8 @@ class SoapboxConfig extends ImmutablePureComponent { name='copyright' label={intl.formatMessage(messages.copyrightFooterLabel)} placeholder={intl.formatMessage(messages.copyrightFooterLabel)} - value={copyright} - onChange={this.handleTextChange} + value={soapbox.get('copyright')} + onChange={this.handleChange(['copyright'], (e) => e.target.value)} /> @@ -329,31 +207,31 @@ class SoapboxConfig extends ImmutablePureComponent { Soapbox Icons List }} /> { - promoPanelItems.valueSeq().map((field, i) => ( + soapbox.getIn(['promoPanel', 'items']).map((field, i) => (
)) }
-
+
@@ -365,25 +243,25 @@ class SoapboxConfig extends ImmutablePureComponent { { - homeFooterItems.valueSeq().map((field, i) => ( + soapbox.getIn(['navlinks', 'homeFooter']).map((field, i) => (
)) }
-
+
@@ -396,19 +274,19 @@ class SoapboxConfig extends ImmutablePureComponent { { - customCssItems.valueSeq().map((field, i) => ( + soapbox.get('customCss').map((field, i) => (
e.target.value)} />
)) }
-
+