From 93d2e835843857f60c59e756e58940c10033a2b6 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Thu, 1 Oct 2020 18:57:11 -0500 Subject: [PATCH 1/3] SoapboxConfig: site preview --- app/soapbox/actions/settings.js | 2 +- .../soapbox_config/components/site_preview.js | 56 +++++++ app/soapbox/features/soapbox_config/index.js | 68 +------- app/soapbox/utils/theme.js | 2 + app/styles/components/tabs-bar.scss | 1 + app/styles/forms.scss | 30 ++++ app/styles/holiday/halloween.scss | 155 +++++++++--------- app/styles/themes.scss | 7 +- 8 files changed, 180 insertions(+), 141 deletions(-) create mode 100644 app/soapbox/features/soapbox_config/components/site_preview.js diff --git a/app/soapbox/actions/settings.js b/app/soapbox/actions/settings.js index 205250c3b..03b538bcc 100644 --- a/app/soapbox/actions/settings.js +++ b/app/soapbox/actions/settings.js @@ -9,7 +9,7 @@ export const SETTING_SAVE = 'SETTING_SAVE'; export const FE_NAME = 'soapbox_fe'; -const defaultSettings = ImmutableMap({ +export const defaultSettings = ImmutableMap({ onboarded: false, skinTone: 1, diff --git a/app/soapbox/features/soapbox_config/components/site_preview.js b/app/soapbox/features/soapbox_config/components/site_preview.js new file mode 100644 index 000000000..725ed3079 --- /dev/null +++ b/app/soapbox/features/soapbox_config/components/site_preview.js @@ -0,0 +1,56 @@ +import React from 'react'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import classNames from 'classnames'; +import { defaultSettings } from 'soapbox/actions/settings'; +import { brandColorToCSS } from 'soapbox/utils/theme'; + +export default function SitePreview({ soapbox }) { + + const settings = defaultSettings.mergeDeep(soapbox.get('defaultSettings')); + + const bodyClass = classNames('site-preview app-body', `theme-mode-${settings.get('themeMode')}`, { + 'system-font': settings.get('systemFont'), + 'no-reduce-motion': !settings.get('reduceMotion'), + 'dyslexic': settings.get('dyslexicFont'), + 'demetricator': settings.get('demetricator'), + 'halloween': settings.get('halloween'), + }); + + return ( +
+ +
+
+
+ +
+ Site Preview +
+
+
+
+
+ ); + +} + +SitePreview.propTypes = { + soapbox: ImmutablePropTypes.map.isRequired, +}; diff --git a/app/soapbox/features/soapbox_config/index.js b/app/soapbox/features/soapbox_config/index.js index d6823cee0..6038f9961 100644 --- a/app/soapbox/features/soapbox_config/index.js +++ b/app/soapbox/features/soapbox_config/index.js @@ -23,6 +23,7 @@ import Overlay from 'react-overlays/lib/Overlay'; import { isMobile } from 'soapbox/is_mobile'; import detectPassiveEvents from 'detect-passive-events'; import Accordion from '../ui/components/accordion'; +import SitePreview from './components/site_preview'; const messages = defineMessages({ heading: { id: 'column.soapbox_config', defaultMessage: 'Soapbox config' }, @@ -190,10 +191,16 @@ class SoapboxConfig extends ImmutablePureComponent {
+
- + } + value={soapbox.get('brandColor')} + onChange={this.handleChange(['brandColor'], (e) => e.hex)} + />
- {/*
-
- -
-
- } - name='banner' - hint={} - onChange={this.handleFileChange(['banner'])} - /> -
-
*/}
- -
- } - value={soapbox.get('brandColor')} - onChange={this.handleChange(['brandColor'], (e) => e.hex)} - /> -
-
- {/* - } - hint={} - name='patron' - checked={soapbox.getIn(['extensions', 'patron', 'enabled'])} - onChange={this.handleChange( - ['extensions', 'patron', 'enabled'], (e) => e.checked, - )} - /> - */} - {/*
- - - - - { - soapbox.get('customCss').map((field, i) => ( -
- e.target.value)} - /> - -
- )) - } -
-
- - -
-
-
*/}
( .entrySeq() .reduce((acc, cur) => acc + `--${cur[0]}:${cur[1]};`, '') ); + +export const brandColorToCSS = brandColor => themeDataToCss(brandColorToThemeData(brandColor)); diff --git a/app/styles/components/tabs-bar.scss b/app/styles/components/tabs-bar.scss index a9cf3b1d4..808b21fde 100644 --- a/app/styles/components/tabs-bar.scss +++ b/app/styles/components/tabs-bar.scss @@ -5,6 +5,7 @@ flex: 0 0 auto; overflow-y: auto; height: 50px; + width: 100%; position: sticky; top: 0; z-index: 1000; diff --git a/app/styles/forms.scss b/app/styles/forms.scss index 8338f2af3..9829ce280 100644 --- a/app/styles/forms.scss +++ b/app/styles/forms.scss @@ -705,3 +705,33 @@ code { cursor: pointer; color: $error-red; } + +.site-preview { + border-radius: 4px; + overflow: hidden; + height: 164px; + border: 1px solid; + margin-bottom: 40px; + background: var(--background-color); + + * { + z-index: 0; + } + + a { + cursor: default; + } + + .ui { + display: flex; + flex-direction: column; + padding: 0; + height: 100%; + } + + .page { + align-items: center; + justify-content: center; + height: 100%; + } +} diff --git a/app/styles/holiday/halloween.scss b/app/styles/holiday/halloween.scss index b63a1ed0f..ad190a18b 100644 --- a/app/styles/holiday/halloween.scss +++ b/app/styles/holiday/halloween.scss @@ -1,4 +1,5 @@ -body.halloween { +.halloween, +.site-preview.halloween { // Set brand color to orange --brand-color_h: 29.727272727272727; --brand-color_s: 100%; @@ -14,8 +15,8 @@ body.halloween { // Full-screen pseudo-elements to hold BG graphics &::before, &::after, - .app-holder::before, - .app-holder::after { + > .app-holder::before, + > .app-holder::after { content: ''; display: block; position: fixed; @@ -42,7 +43,7 @@ body.halloween { animation: halloween-twinkle 200s linear infinite; } - .app-holder { + > .app-holder { // Vignette &::before { background-image: radial-gradient( @@ -58,90 +59,90 @@ body.halloween { background: transparent url("../images/halloween/clouds.png") repeat top center; animation: halloween-clouds 200s linear infinite; } - } - // Dangling spider - .ui .page__top::after, - .ui .page__columns::after { - content: ''; - display: block; - width: 100px; - height: 100px; - right: 20px; - background-image: url('../images/halloween/spider.svg'); - background-size: contain; - background-repeat: no-repeat; - background-position: top right; - z-index: -1; - pointer-events: none; - } - - .ui .page__columns::after { - position: fixed; - top: 50px; - } - - .ui .page__top::after { - position: absolute; - bottom: -100px; - } - - .ui .page__top + .page__columns::after { - display: none; - } - - // Witch emblem - .getting-started__footer::before { - content: ''; - display: block; - background-image: url('../images/halloween/halloween-emblem.svg'); - background-size: contain; - background-position: left; - background-repeat: no-repeat; - width: 100%; - height: 100px; - margin-bottom: 20px; - } - - // Color fixes - // Elements directly over the BG need static colors that don't change - // regardless of the theme-mode - .getting-started__footer { - color: #fff; - - a { - color: hsla(0, 0%, 100%, 0.4); + // Dangling spider + .ui .page__top::after, + .ui .page__columns::after { + content: ''; + display: block; + width: 100px; + height: 100px; + right: 20px; + background-image: url('../images/halloween/spider.svg'); + background-size: contain; + background-repeat: no-repeat; + background-position: top right; + z-index: -1; + pointer-events: none; } - p { - color: hsla(0, 0%, 100%, 0.8); + .ui .page__columns::after { + position: fixed; + top: 50px; } - } - .profile-info-panel { - color: #fff; + .ui .page__top::after { + position: absolute; + bottom: -100px; + } - &-content__name h1 { - span:first-of-type { - color: hsla(0, 0%, 100%, 0.6); + .ui .page__top + .page__columns::after { + display: none; + } + + // Witch emblem + .getting-started__footer::before { + content: ''; + display: block; + background-image: url('../images/halloween/halloween-emblem.svg'); + background-size: contain; + background-position: left; + background-repeat: no-repeat; + width: 100%; + height: 100px; + margin-bottom: 20px; + } + + // Color fixes + // Elements directly over the BG need static colors that don't change + // regardless of the theme-mode + .getting-started__footer { + color: #fff; + + a { + color: hsla(0, 0%, 100%, 0.4); } - small { + p { + color: hsla(0, 0%, 100%, 0.8); + } + } + + .profile-info-panel { + color: #fff; + + &-content__name h1 { + span:first-of-type { + color: hsla(0, 0%, 100%, 0.6); + } + + small { + color: #fff; + } + } + + &-content__bio { color: #fff; } - } - &-content__bio { - color: #fff; - } - - &-content__bio a, - &-content__fields a { - color: hsl( - var(--brand-color_h), - var(--brand-color_s), - calc(var(--brand-color_l) + 8%) - ); + &-content__bio a, + &-content__fields a { + color: hsl( + var(--brand-color_h), + var(--brand-color_s), + calc(var(--brand-color_l) + 8%) + ); + } } } } diff --git a/app/styles/themes.scss b/app/styles/themes.scss index a670b3086..fb7b89bbd 100644 --- a/app/styles/themes.scss +++ b/app/styles/themes.scss @@ -24,7 +24,8 @@ Examples: --primary-text-color--faint */ -body { +body, +.site-preview { // Primary variables --brand-color: hsl(var(--brand-color_hsl)); --accent-color: hsl(var(--accent-color_hsl)); @@ -56,7 +57,7 @@ body { --warning-color--faint: hsla(var(--warning-color_hsl), 0.5); } -body.theme-mode-light { +.theme-mode-light { // Primary variables --foreground-color: #ffffff; --highlight-text-color: hsl( @@ -85,7 +86,7 @@ body.theme-mode-light { ); } -body.theme-mode-dark { +.theme-mode-dark { // Primary variables --foreground-color: #222222; --highlight-text-color: hsl( From 3a0b58315f1958eb28ad7f17759ad566b34b44f5 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Thu, 1 Oct 2020 19:33:03 -0500 Subject: [PATCH 2/3] SoapboxConfig: add a default themeMode toggle --- app/soapbox/components/sidebar_menu.js | 2 +- app/soapbox/features/soapbox_config/index.js | 7 +++++++ .../features/ui/components/tabs_bar.js | 2 +- .../features/ui/components/theme_toggle.js | 21 +++---------------- .../ui/components/theme_toggle_container.js | 17 +++++++++++++++ 5 files changed, 29 insertions(+), 20 deletions(-) create mode 100644 app/soapbox/features/ui/components/theme_toggle_container.js diff --git a/app/soapbox/components/sidebar_menu.js b/app/soapbox/components/sidebar_menu.js index ea9f753d4..f0e407033 100644 --- a/app/soapbox/components/sidebar_menu.js +++ b/app/soapbox/components/sidebar_menu.js @@ -15,7 +15,7 @@ import { shortNumberFormat } from '../utils/numbers'; import { isStaff } from '../utils/accounts'; import { makeGetAccount } from '../selectors'; import { logOut } from 'soapbox/actions/auth'; -import ThemeToggle from '../features/ui/components/theme_toggle'; +import ThemeToggle from '../features/ui/components/theme_toggle_container'; const messages = defineMessages({ followers: { id: 'account.followers', defaultMessage: 'Followers' }, diff --git a/app/soapbox/features/soapbox_config/index.js b/app/soapbox/features/soapbox_config/index.js index 6038f9961..2dd444279 100644 --- a/app/soapbox/features/soapbox_config/index.js +++ b/app/soapbox/features/soapbox_config/index.js @@ -24,6 +24,8 @@ import { isMobile } from 'soapbox/is_mobile'; import detectPassiveEvents from 'detect-passive-events'; import Accordion from '../ui/components/accordion'; import SitePreview from './components/site_preview'; +import ThemeToggle from 'soapbox/features/ui/components/theme_toggle'; +import { defaultSettings } from 'soapbox/actions/settings'; const messages = defineMessages({ heading: { id: 'column.soapbox_config', defaultMessage: 'Soapbox config' }, @@ -186,6 +188,7 @@ class SoapboxConfig extends ImmutablePureComponent { render() { const { intl } = this.props; const soapbox = this.getSoapboxConfig(); + const settings = defaultSettings.mergeDeep(soapbox.get('defaultSettings')); return ( @@ -201,6 +204,10 @@ class SoapboxConfig extends ImmutablePureComponent { value={soapbox.get('brandColor')} onChange={this.handleChange(['brandColor'], (e) => e.hex)} /> + value)} + settings={settings} + />
{ - return { - settings: getSettings(state), - }; -}; - -const mapDispatchToProps = (dispatch) => ({ - toggleTheme(setting) { - dispatch(changeSetting(['themeMode'], setting)); - }, -}); - -export default @connect(mapStateToProps, mapDispatchToProps) -@injectIntl +export default @injectIntl class ThemeToggle extends React.PureComponent { static propTypes = { intl: PropTypes.object.isRequired, settings: ImmutablePropTypes.map.isRequired, - toggleTheme: PropTypes.func, + onToggle: PropTypes.func.isRequired, showLabel: PropTypes.bool, }; handleToggleTheme = () => { - this.props.toggleTheme(this.props.settings.get('themeMode') === 'light' ? 'dark' : 'light'); + this.props.onToggle(this.props.settings.get('themeMode') === 'light' ? 'dark' : 'light'); } render() { diff --git a/app/soapbox/features/ui/components/theme_toggle_container.js b/app/soapbox/features/ui/components/theme_toggle_container.js new file mode 100644 index 000000000..4a2cad1f7 --- /dev/null +++ b/app/soapbox/features/ui/components/theme_toggle_container.js @@ -0,0 +1,17 @@ +import { connect } from 'react-redux'; +import { changeSetting, getSettings } from 'soapbox/actions/settings'; +import ThemeToggle from './theme_toggle'; + +const mapStateToProps = state => { + return { + settings: getSettings(state), + }; +}; + +const mapDispatchToProps = (dispatch) => ({ + onToggle(setting) { + dispatch(changeSetting(['themeMode'], setting)); + }, +}); + +export default connect(mapStateToProps, mapDispatchToProps)(ThemeToggle); From b99bb7bd4b2f87e5d178a0fc727ebcc3d7dbef01 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Thu, 1 Oct 2020 19:44:40 -0500 Subject: [PATCH 3/3] SoapboxConfig: improve layout --- app/soapbox/features/soapbox_config/index.js | 130 +++++++++---------- 1 file changed, 64 insertions(+), 66 deletions(-) diff --git a/app/soapbox/features/soapbox_config/index.js b/app/soapbox/features/soapbox_config/index.js index 2dd444279..50ba5257d 100644 --- a/app/soapbox/features/soapbox_config/index.js +++ b/app/soapbox/features/soapbox_config/index.js @@ -229,76 +229,74 @@ class SoapboxConfig extends ImmutablePureComponent { /> -
-
- - - - - - Soapbox Icons List }} /> - - { - soapbox.getIn(['promoPanel', 'items']).map((field, i) => ( -
- - - - -
- )) - } -
-
- - +
+ + + + + + Soapbox Icons List }} /> + + { + soapbox.getIn(['promoPanel', 'items']).map((field, i) => ( +
+ + + +
+ )) + } +
+
+ +
-
- - - - - { - soapbox.getIn(['navlinks', 'homeFooter']).map((field, i) => ( -
- - - -
- )) - } -
-
- - +
+
+ + + + + { + soapbox.getIn(['navlinks', 'homeFooter']).map((field, i) => ( +
+ + +
+ )) + } +
+
+ +