SoapboxConfig: site preview

This commit is contained in:
Alex Gleason 2020-10-01 18:57:11 -05:00
parent 58d5b1940e
commit 93d2e83584
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
8 changed files with 180 additions and 141 deletions

View File

@ -9,7 +9,7 @@ export const SETTING_SAVE = 'SETTING_SAVE';
export const FE_NAME = 'soapbox_fe'; export const FE_NAME = 'soapbox_fe';
const defaultSettings = ImmutableMap({ export const defaultSettings = ImmutableMap({
onboarded: false, onboarded: false,
skinTone: 1, skinTone: 1,

View File

@ -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 (
<div className={bodyClass}>
<style>{`.site-preview {${brandColorToCSS(soapbox.get('brandColor'))}}`}</style>
<div className='app-holder'>
<div>
<div className='ui'>
<nav className='tabs-bar'>
<div className='tabs-bar__container'>
<div className='tabs-bar__split tabs-bar__split--left'>
<a className='tabs-bar__link--logo' href='#'>
<img alt='Logo' src={soapbox.get('logo')} />
<span>Home</span>
</a>
<a className='tabs-bar__link' href='#'>
<i role='img' alt='home' className='fa fa-home' />
<span>Home</span>
</a>
<a className='tabs-bar__link' href='#'>
<i role='img' alt='bell' className='fa fa-bell' />
<span>Notifications</span>
</a>
</div>
</div>
</nav>
<div className='page'>
<span className='spoiler-button__overlay__label'>Site Preview</span>
</div>
</div>
</div>
</div>
</div>
);
}
SitePreview.propTypes = {
soapbox: ImmutablePropTypes.map.isRequired,
};

View File

@ -23,6 +23,7 @@ import Overlay from 'react-overlays/lib/Overlay';
import { isMobile } from 'soapbox/is_mobile'; import { isMobile } from 'soapbox/is_mobile';
import detectPassiveEvents from 'detect-passive-events'; import detectPassiveEvents from 'detect-passive-events';
import Accordion from '../ui/components/accordion'; import Accordion from '../ui/components/accordion';
import SitePreview from './components/site_preview';
const messages = defineMessages({ const messages = defineMessages({
heading: { id: 'column.soapbox_config', defaultMessage: 'Soapbox config' }, heading: { id: 'column.soapbox_config', defaultMessage: 'Soapbox config' },
@ -190,10 +191,16 @@ class SoapboxConfig extends ImmutablePureComponent {
<Column icon='cog' heading={intl.formatMessage(messages.heading)} backBtnSlim> <Column icon='cog' heading={intl.formatMessage(messages.heading)} backBtnSlim>
<SimpleForm onSubmit={this.handleSubmit}> <SimpleForm onSubmit={this.handleSubmit}>
<fieldset disabled={this.state.isLoading}> <fieldset disabled={this.state.isLoading}>
<SitePreview soapbox={soapbox} />
<FieldsGroup> <FieldsGroup>
<div className='fields-row file-picker'> <div className='fields-row file-picker'>
<div className='fields-row__column fields-row__column-6'> <div className='fields-row__column fields-row__column-6'>
<img src={soapbox.get('logo')} /> <ColorWithPicker
buttonId='brand_color'
label={<FormattedMessage id='soapbox_config.fields.brand_color_label' defaultMessage='Brand color' />}
value={soapbox.get('brandColor')}
onChange={this.handleChange(['brandColor'], (e) => e.hex)}
/>
</div> </div>
<div className='fields-row__column fields-group fields-row__column-6'> <div className='fields-row__column fields-group fields-row__column-6'>
<FileChooserLogo <FileChooserLogo
@ -204,41 +211,7 @@ class SoapboxConfig extends ImmutablePureComponent {
/> />
</div> </div>
</div> </div>
{/*<div className='fields-row file-picker'>
<div className='fields-row__column fields-row__column-6'>
<img src={soapbox.get('banner')} />
</div>
<div className='fields-row__column fields-group fields-row__column-6'>
<FileChooser
label={<FormattedMessage id='soapbox_config.fields.banner_label' defaultMessage='Banner' />}
name='banner'
hint={<FormattedMessage id='soapbox_config.hints.banner' defaultMessage='PNG, GIF or JPG. At most 2 MB. Will be displayed to 400x400px' />}
onChange={this.handleFileChange(['banner'])}
/>
</div>
</div>*/}
</FieldsGroup> </FieldsGroup>
<FieldsGroup>
<div className='fields-row__column fields-group'>
<ColorWithPicker
buttonId='brand_color'
label={<FormattedMessage id='soapbox_config.fields.brand_color_label' defaultMessage='Brand color' />}
value={soapbox.get('brandColor')}
onChange={this.handleChange(['brandColor'], (e) => e.hex)}
/>
</div>
</FieldsGroup>
{/*<FieldsGroup>
<Checkbox
label={<FormattedMessage id='soapbox_config.fields.patron_enabled_label' defaultMessage='Patron module' />}
hint={<FormattedMessage id='soapbox_config.hints.patron_enabled' defaultMessage='Enables display of Patron module. Requires installation of Patron module.' />}
name='patron'
checked={soapbox.getIn(['extensions', 'patron', 'enabled'])}
onChange={this.handleChange(
['extensions', 'patron', 'enabled'], (e) => e.checked,
)}
/>
</FieldsGroup>*/}
<FieldsGroup> <FieldsGroup>
<TextInput <TextInput
name='copyright' name='copyright'
@ -322,31 +295,6 @@ class SoapboxConfig extends ImmutablePureComponent {
</div> </div>
</div> </div>
</div> </div>
{/* <div className='input with_block_label'>
<label><FormattedMessage id='soapbox_config.fields.custom_css_fields_label' defaultMessage='Custom CSS' /></label>
<span className='hint'>
<FormattedMessage id='soapbox_config.hints.custom_css_fields' defaultMessage='Insert a URL to a CSS file like `https://mysite.com/instance/custom.css`, or simply `/instance/custom.css`' />
</span>
{
soapbox.get('customCss').map((field, i) => (
<div className='row' key={i}>
<TextInput
label={intl.formatMessage(messages.customCssLabel)}
placeholder={intl.formatMessage(messages.customCssLabel)}
value={field}
onChange={this.handleChange(['customCss', i], (e) => e.target.value)}
/>
<Icon id='times-circle' onClick={this.handleDeleteItem(['customCss', i])} />
</div>
))
}
<div className='actions'>
<div name='button' type='button' role='presentation' className='btn button button-secondary' onClick={this.handleAddItem(['customCss'], '')}>
<Icon id='plus-circle' />
<FormattedMessage id='soapbox_config.fields.custom_css.add' defaultMessage='Add another custom CSS URL' />
</div>
</div>
</div> */}
</FieldsGroup> </FieldsGroup>
<Accordion <Accordion
headline={intl.formatMessage(messages.rawJSONLabel)} headline={intl.formatMessage(messages.rawJSONLabel)}

View File

@ -79,3 +79,5 @@ export const themeDataToCss = themeData => (
.entrySeq() .entrySeq()
.reduce((acc, cur) => acc + `--${cur[0]}:${cur[1]};`, '') .reduce((acc, cur) => acc + `--${cur[0]}:${cur[1]};`, '')
); );
export const brandColorToCSS = brandColor => themeDataToCss(brandColorToThemeData(brandColor));

View File

@ -5,6 +5,7 @@
flex: 0 0 auto; flex: 0 0 auto;
overflow-y: auto; overflow-y: auto;
height: 50px; height: 50px;
width: 100%;
position: sticky; position: sticky;
top: 0; top: 0;
z-index: 1000; z-index: 1000;

View File

@ -705,3 +705,33 @@ code {
cursor: pointer; cursor: pointer;
color: $error-red; 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%;
}
}

View File

@ -1,4 +1,5 @@
body.halloween { .halloween,
.site-preview.halloween {
// Set brand color to orange // Set brand color to orange
--brand-color_h: 29.727272727272727; --brand-color_h: 29.727272727272727;
--brand-color_s: 100%; --brand-color_s: 100%;
@ -14,8 +15,8 @@ body.halloween {
// Full-screen pseudo-elements to hold BG graphics // Full-screen pseudo-elements to hold BG graphics
&::before, &::before,
&::after, &::after,
.app-holder::before, > .app-holder::before,
.app-holder::after { > .app-holder::after {
content: ''; content: '';
display: block; display: block;
position: fixed; position: fixed;
@ -42,7 +43,7 @@ body.halloween {
animation: halloween-twinkle 200s linear infinite; animation: halloween-twinkle 200s linear infinite;
} }
.app-holder { > .app-holder {
// Vignette // Vignette
&::before { &::before {
background-image: radial-gradient( background-image: radial-gradient(
@ -58,90 +59,90 @@ body.halloween {
background: transparent url("../images/halloween/clouds.png") repeat top center; background: transparent url("../images/halloween/clouds.png") repeat top center;
animation: halloween-clouds 200s linear infinite; animation: halloween-clouds 200s linear infinite;
} }
}
// Dangling spider // Dangling spider
.ui .page__top::after, .ui .page__top::after,
.ui .page__columns::after { .ui .page__columns::after {
content: ''; content: '';
display: block; display: block;
width: 100px; width: 100px;
height: 100px; height: 100px;
right: 20px; right: 20px;
background-image: url('../images/halloween/spider.svg'); background-image: url('../images/halloween/spider.svg');
background-size: contain; background-size: contain;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: top right; background-position: top right;
z-index: -1; z-index: -1;
pointer-events: none; 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);
} }
p { .ui .page__columns::after {
color: hsla(0, 0%, 100%, 0.8); position: fixed;
top: 50px;
} }
}
.profile-info-panel { .ui .page__top::after {
color: #fff; position: absolute;
bottom: -100px;
}
&-content__name h1 { .ui .page__top + .page__columns::after {
span:first-of-type { display: none;
color: hsla(0, 0%, 100%, 0.6); }
// 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; color: #fff;
} }
}
&-content__bio { &-content__bio a,
color: #fff; &-content__fields a {
} color: hsl(
var(--brand-color_h),
&-content__bio a, var(--brand-color_s),
&-content__fields a { calc(var(--brand-color_l) + 8%)
color: hsl( );
var(--brand-color_h), }
var(--brand-color_s),
calc(var(--brand-color_l) + 8%)
);
} }
} }
} }

View File

@ -24,7 +24,8 @@ Examples:
--primary-text-color--faint --primary-text-color--faint
*/ */
body { body,
.site-preview {
// Primary variables // Primary variables
--brand-color: hsl(var(--brand-color_hsl)); --brand-color: hsl(var(--brand-color_hsl));
--accent-color: hsl(var(--accent-color_hsl)); --accent-color: hsl(var(--accent-color_hsl));
@ -56,7 +57,7 @@ body {
--warning-color--faint: hsla(var(--warning-color_hsl), 0.5); --warning-color--faint: hsla(var(--warning-color_hsl), 0.5);
} }
body.theme-mode-light { .theme-mode-light {
// Primary variables // Primary variables
--foreground-color: #ffffff; --foreground-color: #ffffff;
--highlight-text-color: hsl( --highlight-text-color: hsl(
@ -85,7 +86,7 @@ body.theme-mode-light {
); );
} }
body.theme-mode-dark { .theme-mode-dark {
// Primary variables // Primary variables
--foreground-color: #222222; --foreground-color: #222222;
--highlight-text-color: hsl( --highlight-text-color: hsl(