From ec42888fff312ddcf1a8ebe5bf254160c79a3f76 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sun, 23 Aug 2020 15:56:18 -0500 Subject: [PATCH] Add getSoapboxConfig() like getSettings() --- app/soapbox/actions/soapbox.js | 21 ++++++++++++++ app/soapbox/containers/soapbox.js | 6 ++-- .../features/account_timeline/index.js | 4 ++- .../public_layout/components/footer.js | 13 ++++++--- .../public_layout/components/site_banner.js | 3 +- .../public_layout/components/site_logo.js | 3 +- app/soapbox/features/public_layout/index.js | 3 +- app/soapbox/features/soapbox_config/index.js | 9 +++--- .../features/ui/components/promo_panel.js | 3 +- .../features/ui/components/tabs_bar.js | 3 +- app/soapbox/pages/home_page.js | 3 +- .../reducers/__tests__/soapbox-test.js | 6 ++-- app/soapbox/reducers/soapbox.js | 28 +++---------------- 13 files changed, 60 insertions(+), 45 deletions(-) diff --git a/app/soapbox/actions/soapbox.js b/app/soapbox/actions/soapbox.js index 12f7f410d..e729a3da2 100644 --- a/app/soapbox/actions/soapbox.js +++ b/app/soapbox/actions/soapbox.js @@ -1,8 +1,29 @@ import api from '../api'; +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({ + logo: '', + banner: '', + brandColor: '#0482d8', // Azure + customCss: ImmutableList(), + promoPanel: ImmutableMap({ + items: ImmutableList(), + }), + extensions: ImmutableMap(), + defaultSettings: ImmutableMap(), + copyright: '♥2020. Copying is an act of love. Please copy and share.', + navlinks: ImmutableMap({ + homeFooter: ImmutableList(), + }), +}); + +export function getSoapboxConfig(state) { + return defaultConfig.mergeDeep(state.get('soapbox')); +} + export function fetchSoapboxConfig() { return (dispatch, getState) => { api(getState).get('/api/pleroma/frontend_configurations').then(response => { diff --git a/app/soapbox/containers/soapbox.js b/app/soapbox/containers/soapbox.js index 473e592ff..2c7d6f85c 100644 --- a/app/soapbox/containers/soapbox.js +++ b/app/soapbox/containers/soapbox.js @@ -23,6 +23,7 @@ import { fetchSoapboxConfig } from 'soapbox/actions/soapbox'; import { fetchMe } from 'soapbox/actions/me'; import PublicLayout from 'soapbox/features/public_layout'; import { getSettings } from 'soapbox/actions/settings'; +import { getSoapboxConfig } from 'soapbox/actions/soapbox'; import { generateThemeCss } from 'soapbox/utils/theme'; import messages from 'soapbox/locales/messages'; @@ -42,6 +43,7 @@ const mapStateToProps = (state) => { const account = state.getIn(['accounts', me]); const showIntroduction = account ? state.getIn(['settings', 'introductionVersion'], 0) < INTRODUCTION_VERSION : false; const settings = getSettings(state); + const soapboxConfig = getSoapboxConfig(state); const locale = settings.get('locale'); return { @@ -52,9 +54,9 @@ const mapStateToProps = (state) => { dyslexicFont: settings.get('dyslexicFont'), demetricator: settings.get('demetricator'), locale: validLocale(locale) ? locale : 'en', - themeCss: generateThemeCss(state.getIn(['soapbox', 'brandColor'])), + themeCss: generateThemeCss(soapboxConfig.get('brandColor')), themeMode: settings.get('themeMode'), - customCss: state.getIn(['soapbox', 'customCss']), + customCss: soapboxConfig.get('customCss'), }; }; diff --git a/app/soapbox/features/account_timeline/index.js b/app/soapbox/features/account_timeline/index.js index 1ce040a3e..21a55181b 100644 --- a/app/soapbox/features/account_timeline/index.js +++ b/app/soapbox/features/account_timeline/index.js @@ -14,6 +14,7 @@ import { fetchAccountIdentityProofs } from '../../actions/identity_proofs'; import MissingIndicator from 'soapbox/components/missing_indicator'; import { NavLink } from 'react-router-dom'; import { fetchPatronAccount } from '../../actions/patron'; +import { getSoapboxConfig } from 'soapbox/actions/soapbox'; const emptyList = ImmutableList(); @@ -21,6 +22,7 @@ const mapStateToProps = (state, { params: { username }, withReplies = false }) = const me = state.get('me'); const accounts = state.getIn(['accounts']); const accountFetchError = (state.getIn(['accounts', -1, 'username'], '').toLowerCase() === username.toLowerCase()); + const soapboxConfig = getSoapboxConfig(state); let accountId = -1; let accountUsername = username; @@ -50,7 +52,7 @@ const mapStateToProps = (state, { params: { username }, withReplies = false }) = isLoading: state.getIn(['timelines', `account:${path}`, 'isLoading']), hasMore: state.getIn(['timelines', `account:${path}`, 'hasMore']), me, - patronEnabled: state.getIn(['soapbox', 'extensions', 'patron', 'enabled']), + patronEnabled: soapboxConfig.getIn(['extensions', 'patron', 'enabled']), }; }; diff --git a/app/soapbox/features/public_layout/components/footer.js b/app/soapbox/features/public_layout/components/footer.js index e7a071b19..d34248bc4 100644 --- a/app/soapbox/features/public_layout/components/footer.js +++ b/app/soapbox/features/public_layout/components/footer.js @@ -5,11 +5,16 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { Link } from 'react-router-dom'; import { List as ImmutableList } from 'immutable'; +import { getSoapboxConfig } from 'soapbox/actions/soapbox'; -const mapStateToProps = (state, props) => ({ - copyright: state.getIn(['soapbox', 'copyright']), - navlinks: state.getIn(['soapbox', 'navlinks', 'homeFooter'], ImmutableList()), -}); +const mapStateToProps = (state, props) => { + const soapboxConfig = getSoapboxConfig(state); + + return { + copyright: soapboxConfig.get('copyright'), + navlinks: soapboxConfig.getIn(['navlinks', 'homeFooter'], ImmutableList()), + }; +}; export default @connect(mapStateToProps) class Footer extends ImmutablePureComponent { diff --git a/app/soapbox/features/public_layout/components/site_banner.js b/app/soapbox/features/public_layout/components/site_banner.js index d51ad9583..2f0775bed 100644 --- a/app/soapbox/features/public_layout/components/site_banner.js +++ b/app/soapbox/features/public_layout/components/site_banner.js @@ -1,10 +1,11 @@ import React from 'react'; import { connect } from 'react-redux'; import ImmutablePureComponent from 'react-immutable-pure-component'; +import { getSoapboxConfig } from 'soapbox/actions/soapbox'; const mapStateToProps = (state, props) => ({ instance: state.get('instance'), - soapbox: state.get('soapbox'), + soapbox: getSoapboxConfig(state), }); class SiteBanner extends ImmutablePureComponent { diff --git a/app/soapbox/features/public_layout/components/site_logo.js b/app/soapbox/features/public_layout/components/site_logo.js index 5729d764a..14a24f691 100644 --- a/app/soapbox/features/public_layout/components/site_logo.js +++ b/app/soapbox/features/public_layout/components/site_logo.js @@ -1,10 +1,11 @@ import React from 'react'; import { connect } from 'react-redux'; import ImmutablePureComponent from 'react-immutable-pure-component'; +import { getSoapboxConfig } from 'soapbox/actions/soapbox'; const mapStateToProps = (state, props) => ({ instance: state.get('instance'), - soapbox: state.get('soapbox'), + soapbox: getSoapboxConfig(state), }); class SiteLogo extends ImmutablePureComponent { diff --git a/app/soapbox/features/public_layout/index.js b/app/soapbox/features/public_layout/index.js index e475d0ac6..3148dd478 100644 --- a/app/soapbox/features/public_layout/index.js +++ b/app/soapbox/features/public_layout/index.js @@ -7,10 +7,11 @@ import Header from './components/header'; import Footer from './components/footer'; import LandingPage from '../landing_page'; import AboutPage from '../about'; +import { getSoapboxConfig } from 'soapbox/actions/soapbox'; const mapStateToProps = (state, props) => ({ instance: state.get('instance'), - soapbox: state.get('soapbox'), + soapbox: getSoapboxConfig(state), }); const wave = ( diff --git a/app/soapbox/features/soapbox_config/index.js b/app/soapbox/features/soapbox_config/index.js index 475f90e71..5bb6817c2 100644 --- a/app/soapbox/features/soapbox_config/index.js +++ b/app/soapbox/features/soapbox_config/index.js @@ -22,6 +22,7 @@ import { } from 'immutable'; import { updateAdminConfig } from 'soapbox/actions/admin'; import Icon from 'soapbox/components/icon'; +import { getSoapboxConfig } from 'soapbox/actions/soapbox'; const messages = defineMessages({ heading: { id: 'column.soapbox_config', defaultMessage: 'Soapbox config' }, @@ -34,11 +35,9 @@ const messages = defineMessages({ customCssLabel: { id: 'soapbox_config.custom_css.meta_fields.url_placeholder', defaultMessage: 'URL' }, }); -const mapStateToProps = state => { - return { - soapbox: state.get('soapbox'), - }; -}; +const mapStateToProps = state => ({ + soapbox: getSoapboxConfig(state), +}); export default @connect(mapStateToProps) @injectIntl diff --git a/app/soapbox/features/ui/components/promo_panel.js b/app/soapbox/features/ui/components/promo_panel.js index 06f686f2f..b91380bbc 100644 --- a/app/soapbox/features/ui/components/promo_panel.js +++ b/app/soapbox/features/ui/components/promo_panel.js @@ -2,9 +2,10 @@ import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; import Icon from 'soapbox/components/icon'; import { connect } from 'react-redux'; +import { getSoapboxConfig } from 'soapbox/actions/soapbox'; const mapStateToProps = state => ({ - promoItems: state.getIn(['soapbox', 'promoPanel', 'items']), + promoItems: getSoapboxConfig(state).getIn(['promoPanel', 'items']), }); export default @connect(mapStateToProps) diff --git a/app/soapbox/features/ui/components/tabs_bar.js b/app/soapbox/features/ui/components/tabs_bar.js index d26f294fe..1772b363f 100644 --- a/app/soapbox/features/ui/components/tabs_bar.js +++ b/app/soapbox/features/ui/components/tabs_bar.js @@ -13,6 +13,7 @@ import { openModal } from '../../../actions/modal'; import { openSidebar } from '../../../actions/sidebar'; import Icon from '../../../components/icon'; import ThemeToggle from '../../ui/components/theme_toggle'; +import { getSoapboxConfig } from 'soapbox/actions/soapbox'; const messages = defineMessages({ post: { id: 'tabs_bar.post', defaultMessage: 'Post' }, @@ -133,7 +134,7 @@ const mapStateToProps = state => { const me = state.get('me'); return { account: state.getIn(['accounts', me]), - logo: state.getIn(['soapbox', 'logo']), + logo: getSoapboxConfig(state).get('logo'), }; }; diff --git a/app/soapbox/pages/home_page.js b/app/soapbox/pages/home_page.js index 81f2c93e3..01f299845 100644 --- a/app/soapbox/pages/home_page.js +++ b/app/soapbox/pages/home_page.js @@ -12,13 +12,14 @@ import ComposeFormContainer from '../features/compose/containers/compose_form_co import Avatar from '../components/avatar'; import { getFeatures } from 'soapbox/utils/features'; // import GroupSidebarPanel from '../features/groups/sidebar_panel'; +import { getSoapboxConfig } from 'soapbox/actions/soapbox'; const mapStateToProps = state => { const me = state.get('me'); return { me, account: state.getIn(['accounts', me]), - hasPatron: state.getIn(['soapbox', 'extensions', 'patron', 'enabled']), + hasPatron: getSoapboxConfig(state).getIn(['extensions', 'patron', 'enabled']), features: getFeatures(state.get('instance')), }; }; diff --git a/app/soapbox/reducers/__tests__/soapbox-test.js b/app/soapbox/reducers/__tests__/soapbox-test.js index a5dd1b8bd..25106faac 100644 --- a/app/soapbox/reducers/__tests__/soapbox-test.js +++ b/app/soapbox/reducers/__tests__/soapbox-test.js @@ -6,9 +6,9 @@ import soapbox from 'soapbox/__fixtures__/soapbox.json'; import soapboxConfig from 'soapbox/__fixtures__/admin_api_frontend_config.json'; describe('soapbox reducer', () => { - // it('should return the initial state', () => { - // expect(reducer(undefined, {})).toEqual(ImmutableMap()); - // }); + it('should return the initial state', () => { + expect(reducer(undefined, {})).toEqual(ImmutableMap()); + }); it('should handle SOAPBOX_CONFIG_REQUEST_SUCCESS', () => { const state = ImmutableMap({ brandColor: '#354e91' }); diff --git a/app/soapbox/reducers/soapbox.js b/app/soapbox/reducers/soapbox.js index 6497231f9..1311c3f88 100644 --- a/app/soapbox/reducers/soapbox.js +++ b/app/soapbox/reducers/soapbox.js @@ -1,26 +1,8 @@ import { ADMIN_CONFIG_UPDATE_SUCCESS } from '../actions/admin'; -import { - SOAPBOX_CONFIG_REQUEST_SUCCESS, - SOAPBOX_CONFIG_REQUEST_FAIL, -} from '../actions/soapbox'; -import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable'; +import { SOAPBOX_CONFIG_REQUEST_SUCCESS } from '../actions/soapbox'; +import { Map as ImmutableMap, fromJS } from 'immutable'; -// TODO: Handle this more like getSettings() -const initialState = ImmutableMap({ - logo: '', - banner: '', - brandColor: '#0482d8', // Azure - customCss: ImmutableList([]), - promoPanel: ImmutableMap({ - items: ImmutableList([]), - }), - extensions: ImmutableMap(), - defaultSettings: ImmutableMap(), - copyright: '♥2020. Copying is an act of love. Please copy and share.', - navlinks: ImmutableMap({ - homeFooter: ImmutableList(), - }), -}); +const initialState = ImmutableMap(); const updateFromAdmin = (state, config) => { // TODO: Generalize this with an API similar to `Pleroma.Config` in Pleroma BE @@ -32,9 +14,7 @@ const updateFromAdmin = (state, config) => { export default function soapbox(state = initialState, action) { switch(action.type) { case SOAPBOX_CONFIG_REQUEST_SUCCESS: - return initialState.mergeDeep(ImmutableMap(fromJS(action.soapboxConfig))); - case SOAPBOX_CONFIG_REQUEST_FAIL: - return initialState; + return fromJS(action.soapboxConfig); case ADMIN_CONFIG_UPDATE_SUCCESS: return updateFromAdmin(state, fromJS(action.config)); default: