logo

mastofe

My custom branche(s) on git.pleroma.social/pleroma/mastofe
commit: c424df5192f346dba5332a4b3a2de43b2f028e0c
parent: 942a2e7d68fc4909f3ea953e89c1b2647242b3ad
Author: Eugen Rochko <eugen@zeonfederated.com>
Date:   Thu,  9 Feb 2017 01:20:09 +0100

Progress on moving color styles to Sass

Diffstat:

Mapp/assets/javascripts/components/components/account.jsx41++++-------------------------------------
Mapp/assets/javascripts/components/components/button.jsx1-
Mapp/assets/javascripts/components/components/column_back_button.jsx11+----------
Mapp/assets/javascripts/components/components/column_back_button_slim.jsx4+---
Mapp/assets/javascripts/components/components/load_more.jsx10+---------
Mapp/assets/javascripts/components/components/missing_indicator.jsx10+---------
Mapp/assets/javascripts/components/components/status.jsx21++++++---------------
Mapp/assets/javascripts/components/components/status_content.jsx18++++--------------
Mapp/assets/javascripts/components/features/account/components/action_bar.jsx29++++++++++-------------------
Mapp/assets/javascripts/components/features/account/components/header.jsx13+++++++------
Mapp/assets/javascripts/components/features/compose/components/compose_form.jsx16++++++++--------
Mapp/assets/javascripts/components/features/compose/components/drawer.jsx45++++++---------------------------------------
Mapp/assets/javascripts/components/features/compose/components/navigation_bar.jsx6+++---
Mapp/assets/javascripts/components/features/compose/components/reply_indicator.jsx7++++---
Mapp/assets/javascripts/components/features/compose/components/search.jsx22++++------------------
Mapp/assets/javascripts/components/features/getting_started/index.jsx2+-
Mapp/assets/javascripts/components/features/status/components/action_bar.jsx5+++--
Mapp/assets/javascripts/components/features/ui/components/column.jsx9+--------
Mapp/assets/javascripts/components/features/ui/components/column_header.jsx2+-
Mapp/assets/javascripts/components/features/ui/components/tabs_bar.jsx33+++++----------------------------
Mapp/assets/javascripts/components/features/ui/index.jsx2+-
Mapp/assets/stylesheets/components.scss268+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22 files changed, 340 insertions(+), 235 deletions(-)

diff --git a/app/assets/javascripts/components/components/account.jsx b/app/assets/javascripts/components/components/account.jsx @@ -13,26 +13,6 @@ const messages = defineMessages({ unblock: { id: 'account.unblock', defaultMessage: 'Unblock' } }); -const outerStyle = { - padding: '10px', - borderBottom: '1px solid #363c4b' -}; - -const itemStyle = { - flex: '1 1 auto', - display: 'block', - color: '#9baec8', - overflow: 'hidden', - textDecoration: 'none', - fontSize: '14px' -}; - -const noteStyle = { - paddingTop: '5px', - fontSize: '12px', - color: '#616b86' -}; - const buttonsStyle = { padding: '10px', height: '18px' @@ -45,16 +25,9 @@ const Account = React.createClass({ me: React.PropTypes.number.isRequired, onFollow: React.PropTypes.func.isRequired, onBlock: React.PropTypes.func.isRequired, - withNote: React.PropTypes.bool, intl: React.PropTypes.object.isRequired }, - getDefaultProps () { - return { - withNote: false - }; - }, - mixins: [PureRenderMixin], handleFollow () { @@ -66,17 +39,13 @@ const Account = React.createClass({ }, render () { - const { account, me, withNote, intl } = this.props; + const { account, me, intl } = this.props; if (!account) { return <div />; } - let note, buttons; - - if (account.get('note').length > 0 && withNote) { - note = <div style={noteStyle}>{account.get('note')}</div>; - } + let buttons; if (account.get('id') !== me && account.get('relationship', null) !== null) { const following = account.getIn(['relationship', 'following']); @@ -93,9 +62,9 @@ const Account = React.createClass({ } return ( - <div style={outerStyle}> + <div className='account'> <div style={{ display: 'flex' }}> - <Permalink key={account.get('id')} style={itemStyle} className='account__display-name' href={account.get('url')} to={`/accounts/${account.get('id')}`}> + <Permalink key={account.get('id')} className='account__display-name' href={account.get('url')} to={`/accounts/${account.get('id')}`}> <div style={{ float: 'left', marginLeft: '12px', marginRight: '10px' }}><Avatar src={account.get('avatar')} size={36} /></div> <DisplayName account={account} /> </Permalink> @@ -104,8 +73,6 @@ const Account = React.createClass({ {buttons} </div> </div> - - {note} </div> ); } diff --git a/app/assets/javascripts/components/components/button.jsx b/app/assets/javascripts/components/components/button.jsx @@ -35,7 +35,6 @@ const Button = React.createClass({ boxSizing: 'border-box', textAlign: 'center', border: '10px none', - color: '#fff', fontSize: '14px', fontWeight: '500', letterSpacing: '0', diff --git a/app/assets/javascripts/components/components/column_back_button.jsx b/app/assets/javascripts/components/components/column_back_button.jsx @@ -1,15 +1,6 @@ import PureRenderMixin from 'react-addons-pure-render-mixin'; import { FormattedMessage } from 'react-intl'; -const outerStyle = { - padding: '15px', - fontSize: '16px', - background: '#2f3441', - flex: '0 0 auto', - cursor: 'pointer', - color: '#2b90d9' -}; - const iconStyle = { display: 'inline-block', marginRight: '5px' @@ -29,7 +20,7 @@ const ColumnBackButton = React.createClass({ render () { return ( - <div onClick={this.handleClick} style={outerStyle} className='column-back-button'> + <div onClick={this.handleClick} className='column-back-button'> <i className='fa fa-fw fa-chevron-left' style={iconStyle} /> <FormattedMessage id='column_back_button.label' defaultMessage='Back' /> </div> diff --git a/app/assets/javascripts/components/components/column_back_button_slim.jsx b/app/assets/javascripts/components/components/column_back_button_slim.jsx @@ -7,10 +7,8 @@ const outerStyle = { top: '-48px', padding: '15px', fontSize: '16px', - background: '#2f3441', flex: '0 0 auto', - cursor: 'pointer', - color: '#2b90d9' + cursor: 'pointer' }; const iconStyle = { diff --git a/app/assets/javascripts/components/components/load_more.jsx b/app/assets/javascripts/components/components/load_more.jsx @@ -1,15 +1,7 @@ import { FormattedMessage } from 'react-intl'; -const loadMoreStyle = { - display: 'block', - color: '#616b86', - textAlign: 'center', - padding: '15px', - textDecoration: 'none' -}; - const LoadMore = ({ onClick }) => ( - <a href='#' className='load-more' onClick={onClick} style={loadMoreStyle}> + <a href='#' className='load-more' onClick={onClick}> <FormattedMessage id='status.load_more' defaultMessage='Load more' /> </a> ); diff --git a/app/assets/javascripts/components/components/missing_indicator.jsx b/app/assets/javascripts/components/components/missing_indicator.jsx @@ -1,15 +1,7 @@ import { FormattedMessage } from 'react-intl'; -const style = { - textAlign: 'center', - fontSize: '16px', - fontWeight: '500', - color: '#616b86', - paddingTop: '120px' -}; - const MissingIndicator = () => ( - <div style={style}> + <div className='missing-indicator'> <FormattedMessage id='missing_indicator.label' defaultMessage='Not found' /> </div> ); diff --git a/app/assets/javascripts/components/components/status.jsx b/app/assets/javascripts/components/components/status.jsx @@ -11,15 +11,6 @@ import { FormattedMessage } from 'react-intl'; import emojify from '../emoji'; import escapeTextContentForBrowser from 'react/lib/escapeTextContentForBrowser'; -const outerStyle = { - padding: '8px 10px', - paddingLeft: '68px', - position: 'relative', - minHeight: '48px', - borderBottom: '1px solid #363c4b', - cursor: 'default' -}; - const Status = React.createClass({ contextTypes: { @@ -55,7 +46,7 @@ const Status = React.createClass({ render () { let media = ''; - const { status, now, ...other } = this.props; + const { status, ...other } = this.props; if (status === null) { return <div />; @@ -72,9 +63,9 @@ const Status = React.createClass({ return ( <div style={{ cursor: 'default' }}> - <div style={{ marginLeft: '68px', color: '#616b86', padding: '8px 0', paddingBottom: '2px', fontSize: '14px', position: 'relative' }}> + <div className='status__prepend'> <div style={{ position: 'absolute', 'left': '-26px'}}><i className='fa fa-fw fa-retweet' /></div> - <FormattedMessage id='status.reblogged_by' defaultMessage='{name} reblogged' values={{ name: <a onClick={this.handleAccountClick.bind(this, status.getIn(['account', 'id']))} href={status.getIn(['account', 'url'])} className='status__display-name muted'><strong style={{ color: '#616b86'}} dangerouslySetInnerHTML={displayNameHTML} /></a> }} /> + <FormattedMessage id='status.reblogged_by' defaultMessage='{name} reblogged' values={{ name: <a onClick={this.handleAccountClick.bind(this, status.getIn(['account', 'id']))} href={status.getIn(['account', 'url'])} className='status__display-name muted'><strong dangerouslySetInnerHTML={displayNameHTML} /></a> }} /> </div> <Status {...other} wrapped={true} status={status.get('reblog')} /> @@ -91,13 +82,13 @@ const Status = React.createClass({ } return ( - <div className={this.props.muted ? 'muted' : ''} style={outerStyle}> + <div className={this.props.muted ? 'status muted' : 'status'}> <div style={{ fontSize: '15px' }}> <div style={{ float: 'right', fontSize: '14px' }}> - <a href={status.get('url')} className='status__relative-time' style={{ color: '#616b86' }} target='_blank' rel='noopener'><RelativeTimestamp timestamp={status.get('created_at')} now={now} /></a> + <a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener'><RelativeTimestamp timestamp={status.get('created_at')} /></a> </div> - <a onClick={this.handleAccountClick.bind(this, status.getIn(['account', 'id']))} href={status.getIn(['account', 'url'])} className='status__display-name' style={{ display: 'block', maxWidth: '100%', paddingRight: '25px', color: '#616b86' }}> + <a onClick={this.handleAccountClick.bind(this, status.getIn(['account', 'id']))} href={status.getIn(['account', 'url'])} className='status__display-name' style={{ display: 'block', maxWidth: '100%', paddingRight: '25px' }}> <div className='status__avatar' style={{ position: 'absolute', left: '10px', top: '10px', width: '48px', height: '48px' }}> <Avatar src={status.getIn(['account', 'avatar'])} size={48} /> </div> diff --git a/app/assets/javascripts/components/components/status_content.jsx b/app/assets/javascripts/components/components/status_content.jsx @@ -5,17 +5,6 @@ import emojify from '../emoji'; import { FormattedMessage } from 'react-intl'; import Permalink from './permalink'; -const spoilerStyle = { - display: 'inline-block', - borderRadius: '2px', - color: '#363c4b', - fontWeight: '500', - fontSize: '11px', - padding: '0px 6px', - textTransform: 'uppercase', - lineHeight: 'inherit' -}; - const StatusContent = React.createClass({ contextTypes: { @@ -42,7 +31,7 @@ const StatusContent = React.createClass({ for (var i = 0; i < links.length; ++i) { let link = links[i]; let mention = this.props.status.get('mentions').find(item => link.href === item.get('url')); - let media = this.props.status.get('media_attachments').find(item => link.href === item.get('text_url') || link.href === item.get('remote_url')); + let media = this.props.status.get('media_attachments').find(item => link.href === item.get('text_url') || (item.get('remote_url').length > 0 && link.href === item.get('remote_url'))); if (mention) { link.addEventListener('click', this.onMentionClick.bind(this, mention), false); @@ -92,7 +81,8 @@ const StatusContent = React.createClass({ this.startXY = null; }, - handleSpoilerClick () { + handleSpoilerClick (e) { + e.preventDefault(); this.setState({ hidden: !this.state.hidden }); }, @@ -121,7 +111,7 @@ const StatusContent = React.createClass({ return ( <div className='status__content' style={{ cursor: 'pointer' }} onMouseDown={this.handleMouseDown} onMouseUp={this.handleMouseUp}> <p style={{ marginBottom: hidden && status.get('mentions').size === 0 ? '0px' : '' }} > - <span dangerouslySetInnerHTML={spoilerContent} /> <a className='status__content__spoiler-link' style={spoilerStyle} onClick={this.handleSpoilerClick}>{toggleText}</a> + <span dangerouslySetInnerHTML={spoilerContent} /> <a className='status__content__spoiler-link' onClick={this.handleSpoilerClick}>{toggleText}</a> </p> {mentionsPlaceholder} diff --git a/app/assets/javascripts/components/features/account/components/action_bar.jsx b/app/assets/javascripts/components/features/account/components/action_bar.jsx @@ -14,15 +14,6 @@ const messages = defineMessages({ block: { id: 'account.block', defaultMessage: 'Block' } }); -const outerStyle = { - borderTop: '1px solid #363c4b', - borderBottom: '1px solid #363c4b', - lineHeight: '36px', - overflow: 'hidden', - flex: '0 0 auto', - display: 'flex' -}; - const outerDropdownStyle = { padding: '10px', flex: '1 1 auto' @@ -64,25 +55,25 @@ const ActionBar = React.createClass({ } return ( - <div style={outerStyle}> + <div className='account__action-bar'> <div style={outerDropdownStyle}> <DropdownMenu items={menu} icon='bars' size={24} direction="right" /> </div> <div style={outerLinksStyle}> - <Link to={`/accounts/${account.get('id')}`} style={{ textDecoration: 'none', overflow: 'hidden', width: '80px', borderLeft: '1px solid #363c4b', padding: '10px', paddingRight: '5px' }}> - <span style={{ display: 'block', textTransform: 'uppercase', fontSize: '11px', color: '#616b86' }}><FormattedMessage id='account.posts' defaultMessage='Posts' /></span> - <span style={{ display: 'block', fontSize: '15px', fontWeight: '500', color: '#fff' }}><FormattedNumber value={account.get('statuses_count')} /></span> + <Link className='account__action-bar__tab' to={`/accounts/${account.get('id')}`}> + <span><FormattedMessage id='account.posts' defaultMessage='Posts' /></span> + <strong><FormattedNumber value={account.get('statuses_count')} /></strong> </Link> - <Link to={`/accounts/${account.get('id')}/following`} style={{ textDecoration: 'none', overflow: 'hidden', width: '80px', borderLeft: '1px solid #363c4b', padding: '10px 5px' }}> - <span style={{ display: 'block', textTransform: 'uppercase', fontSize: '11px', color: '#616b86' }}><FormattedMessage id='account.follows' defaultMessage='Follows' /></span> - <span style={{ display: 'block', fontSize: '15px', fontWeight: '500', color: '#fff' }}><FormattedNumber value={account.get('following_count')} /></span> + <Link className='account__action-bar__tab' to={`/accounts/${account.get('id')}/following`}> + <span><FormattedMessage id='account.follows' defaultMessage='Follows' /></span> + <strong><FormattedNumber value={account.get('following_count')} /></strong> </Link> - <Link to={`/accounts/${account.get('id')}/followers`} style={{ textDecoration: 'none', overflow: 'hidden', width: '80px', padding: '10px 5px', borderLeft: '1px solid #363c4b' }}> - <span style={{ display: 'block', textTransform: 'uppercase', fontSize: '11px', color: '#616b86' }}><FormattedMessage id='account.followers' defaultMessage='Followers' /></span> - <span style={{ display: 'block', fontSize: '15px', fontWeight: '500', color: '#fff' }}><FormattedNumber value={account.get('followers_count')} /></span> + <Link className='account__action-bar__tab' to={`/accounts/${account.get('id')}/followers`}> + <span><FormattedMessage id='account.followers' defaultMessage='Followers' /></span> + <strong><FormattedNumber value={account.get('followers_count')} /></strong> </Link> </div> </div> diff --git a/app/assets/javascripts/components/features/account/components/header.jsx b/app/assets/javascripts/components/features/account/components/header.jsx @@ -16,7 +16,8 @@ const Header = React.createClass({ propTypes: { account: ImmutablePropTypes.map.isRequired, me: React.PropTypes.number.isRequired, - onFollow: React.PropTypes.func.isRequired + onFollow: React.PropTypes.func.isRequired, + intl: React.PropTypes.object.isRequired }, mixins: [PureRenderMixin], @@ -61,18 +62,18 @@ const Header = React.createClass({ const displayNameHTML = { __html: emojify(escapeTextContentForBrowser(displayName)) }; return ( - <div className='account__header' style={{ flex: '0 0 auto', background: '#2f3441', textAlign: 'center', backgroundImage: `url(${account.get('header')})`, backgroundSize: 'cover', backgroundPosition: 'center', position: 'relative' }}> - <div style={{ background: 'rgba(47, 52, 65, 0.9)', padding: '20px 10px' }}> + <div className='account__header' style={{ backgroundImage: `url(${account.get('header')})` }}> + <div style={{ padding: '20px 10px' }}> <a href={account.get('url')} target='_blank' rel='noopener' style={{ display: 'block', color: 'inherit', textDecoration: 'none' }}> <div className='account__header__avatar' style={{ width: '90px', margin: '0 auto', marginBottom: '10px' }}> <img src={account.get('avatar')} alt='' style={{ display: 'block', width: '90px', height: '90px', borderRadius: '90px' }} /> </div> - <span style={{ display: 'inline-block', color: '#fff', fontSize: '20px', lineHeight: '27px', fontWeight: '500' }} className='account__header__display-name' dangerouslySetInnerHTML={displayNameHTML} /> + <span style={{ display: 'inline-block', fontSize: '20px', lineHeight: '27px', fontWeight: '500' }} className='account__header__display-name' dangerouslySetInnerHTML={displayNameHTML} /> </a> - <span style={{ fontSize: '14px', fontWeight: '400', display: 'block', color: '#489fde', marginBottom: '10px' }}>@{account.get('acct')} {lockedIcon}</span> - <div style={{ color: '#d9e1e8', fontSize: '14px' }} className='account__header__content' dangerouslySetInnerHTML={content} /> + <span className='account__header__username' style={{ fontSize: '14px', fontWeight: '400', display: 'block', marginBottom: '10px' }}>@{account.get('acct')} {lockedIcon}</span> + <div style={{ fontSize: '14px' }} className='account__header__content' dangerouslySetInnerHTML={content} /> {info} {actionBtn} diff --git a/app/assets/javascripts/components/features/compose/components/compose_form.jsx b/app/assets/javascripts/components/features/compose/components/compose_form.jsx @@ -166,30 +166,30 @@ const ComposeForm = React.createClass({ <UploadButtonContainer style={{ paddingTop: '4px' }} /> </div> - <label style={{ display: 'block', lineHeight: '24px', verticalAlign: 'middle', marginTop: '10px', borderTop: '1px solid #282c37', paddingTop: '10px' }}> + <label className='compose-form__label with-border' style={{ marginTop: '10px' }}> <Toggle checked={this.props.spoiler} onChange={this.handleChangeSpoilerness} /> - <span style={{ display: 'inline-block', verticalAlign: 'top', marginLeft: '8px', color: '#9baec8' }}><FormattedMessage id='compose_form.spoiler' defaultMessage='Hide text behind warning' /></span> + <span className='compose-form__label__text'><FormattedMessage id='compose_form.spoiler' defaultMessage='Hide text behind warning' /></span> </label> - <label style={{ display: 'block', lineHeight: '24px', verticalAlign: 'middle', borderTop: '1px solid #282c37', paddingTop: '10px' }}> + <label className='compose-form__label with-border'> <Toggle checked={this.props.private} onChange={this.handleChangeVisibility} /> - <span style={{ display: 'inline-block', verticalAlign: 'middle', marginBottom: '14px', marginLeft: '8px', color: '#9baec8' }}><FormattedMessage id='compose_form.private' defaultMessage='Mark as private' /></span> + <span className='compose-form__label__text'><FormattedMessage id='compose_form.private' defaultMessage='Mark as private' /></span> </label> <Motion defaultStyle={{ opacity: (this.props.private || reply_to_other) ? 0 : 100, height: (this.props.private || reply_to_other) ? 39.5 : 0 }} style={{ opacity: spring((this.props.private || reply_to_other) ? 0 : 100), height: spring((this.props.private || reply_to_other) ? 0 : 39.5) }}> {({ opacity, height }) => - <label style={{ display: 'block', lineHeight: '24px', verticalAlign: 'middle', height: `${height}px`, overflow: 'hidden', opacity: opacity / 100 }}> + <label className='compose-form__label' style={{ height: `${height}px`, overflow: 'hidden', opacity: opacity / 100 }}> <Toggle checked={this.props.unlisted} onChange={this.handleChangeListability} /> - <span style={{ display: 'inline-block', verticalAlign: 'middle', marginBottom: '14px', marginLeft: '8px', color: '#9baec8' }}><FormattedMessage id='compose_form.unlisted' defaultMessage='Do not display in public timeline' /></span> + <span className='compose-form__label__text'><FormattedMessage id='compose_form.unlisted' defaultMessage='Do not display in public timeline' /></span> </label> } </Motion> <Motion defaultStyle={{ opacity: 0, height: 0 }} style={{ opacity: spring(this.props.media_count === 0 ? 0 : 100), height: spring(this.props.media_count === 0 ? 0 : 39.5) }}> {({ opacity, height }) => - <label style={{ display: 'block', lineHeight: '24px', verticalAlign: 'middle', height: `${height}px`, overflow: 'hidden', opacity: opacity / 100 }}> + <label className='compose-form__label' style={{ height: `${height}px`, overflow: 'hidden', opacity: opacity / 100 }}> <Toggle checked={this.props.sensitive} onChange={this.handleChangeSensitivity} /> - <span style={{ display: 'inline-block', verticalAlign: 'middle', marginBottom: '14px', marginLeft: '8px', color: '#9baec8' }}><FormattedMessage id='compose_form.sensitive' defaultMessage='Mark media as sensitive' /></span> + <span className='compose-form__label__text'><FormattedMessage id='compose_form.sensitive' defaultMessage='Mark media as sensitive' /></span> </label> } </Motion> diff --git a/app/assets/javascripts/components/features/compose/components/drawer.jsx b/app/assets/javascripts/components/features/compose/components/drawer.jsx @@ -8,58 +8,25 @@ const messages = defineMessages({ logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' } }); -const outerStyle = { - boxSizing: 'border-box', - display: 'flex', - flexDirection: 'column', - overflowY: 'hidden' -}; - -const innerStyle = { - boxSizing: 'border-box', - padding: '0', - display: 'flex', - flexDirection: 'column', - overflowY: 'auto', - flexGrow: '1' -}; - -const tabStyle = { - display: 'block', - flex: '1 1 auto', - padding: '15px', - paddingBottom: '13px', - color: '#9baec8', - textDecoration: 'none', - textAlign: 'center', - fontSize: '16px', - borderBottom: '2px solid transparent' -}; - -const tabActiveStyle = { - color: '#2b90d9', - borderBottom: '2px solid #2b90d9' -}; - const Drawer = ({ children, withHeader, intl }) => { let header = ''; if (withHeader) { header = ( <div className='drawer__header'> - <Link title={intl.formatMessage(messages.start)} style={tabStyle} to='/getting-started'><i className='fa fa-fw fa-asterisk' /></Link> - <Link title={intl.formatMessage(messages.public)} style={tabStyle} to='/timelines/public'><i className='fa fa-fw fa-globe' /></Link> - <a title={intl.formatMessage(messages.preferences)} style={tabStyle} href='/settings/preferences'><i className='fa fa-fw fa-cog' /></a> - <a title={intl.formatMessage(messages.logout)} style={tabStyle} href='/auth/sign_out' data-method='delete'><i className='fa fa-fw fa-sign-out' /></a> + <Link title={intl.formatMessage(messages.start)} className='drawer__tab' to='/getting-started'><i className='fa fa-fw fa-asterisk' /></Link> + <Link title={intl.formatMessage(messages.public)} className='drawer__tab' to='/timelines/public'><i className='fa fa-fw fa-globe' /></Link> + <a title={intl.formatMessage(messages.preferences)} className='drawer__tab' href='/settings/preferences'><i className='fa fa-fw fa-cog' /></a> + <a title={intl.formatMessage(messages.logout)} className='drawer__tab' href='/auth/sign_out' data-method='delete'><i className='fa fa-fw fa-sign-out' /></a> </div> ); } return ( - <div className='drawer' style={outerStyle}> + <div className='drawer'> {header} - <div className='drawer__inner' style={innerStyle}> + <div className='drawer__inner'> {children} </div> </div> diff --git a/app/assets/javascripts/components/features/compose/components/navigation_bar.jsx b/app/assets/javascripts/components/features/compose/components/navigation_bar.jsx @@ -16,11 +16,11 @@ const NavigationBar = React.createClass({ render () { return ( - <div style={{ padding: '10px', display: 'flex', flexShrink: '0', cursor: 'default' }}> + <div className='navigation-bar'> <Permalink href={this.props.account.get('url')} to={`/accounts/${this.props.account.get('id')}`} style={{ textDecoration: 'none' }}><Avatar src={this.props.account.get('avatar')} size={40} /></Permalink> - <div style={{ flex: '1 1 auto', marginLeft: '8px', color: '#9baec8' }}> - <strong style={{ fontWeight: '500', display: 'block', color: '#fff' }}>{this.props.account.get('acct')}</strong> + <div style={{ flex: '1 1 auto', marginLeft: '8px' }}> + <strong style={{ fontWeight: '500', display: 'block' }}>{this.props.account.get('acct')}</strong> <a href='/settings/profile' style={{ color: 'inherit', textDecoration: 'none' }}><FormattedMessage id='navigation_bar.edit_profile' defaultMessage='Edit profile' /></a> </div> </div> diff --git a/app/assets/javascripts/components/features/compose/components/reply_indicator.jsx b/app/assets/javascripts/components/features/compose/components/reply_indicator.jsx @@ -18,7 +18,8 @@ const ReplyIndicator = React.createClass({ propTypes: { status: ImmutablePropTypes.map.isRequired, - onCancel: React.PropTypes.func.isRequired + onCancel: React.PropTypes.func.isRequired, + intl: React.PropTypes.object.isRequired }, mixins: [PureRenderMixin], @@ -39,11 +40,11 @@ const ReplyIndicator = React.createClass({ const content = { __html: emojify(this.props.status.get('content')) }; return ( - <div style={{ background: '#9baec8', padding: '10px' }}> + <div className='reply-indicator'> <div style={{ overflow: 'hidden', marginBottom: '5px' }}> <div style={{ float: 'right', lineHeight: '24px' }}><IconButton title={intl.formatMessage(messages.cancel)} icon='times' onClick={this.handleClick} /></div> - <a href={this.props.status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='reply-indicator__display-name' style={{ display: 'block', maxWidth: '100%', paddingRight: '25px', color: '#282c37', textDecoration: 'none', overflow: 'hidden', lineHeight: '24px' }}> + <a href={this.props.status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='reply-indicator__display-name' style={{ display: 'block', maxWidth: '100%', paddingRight: '25px', textDecoration: 'none', overflow: 'hidden', lineHeight: '24px' }}> <div style={{ float: 'left', marginRight: '5px' }}><Avatar size={24} src={this.props.status.getIn(['account', 'avatar'])} /></div> <DisplayName account={this.props.status.get('account')} /> </a> diff --git a/app/assets/javascripts/components/features/compose/components/search.jsx b/app/assets/javascripts/components/features/compose/components/search.jsx @@ -31,25 +31,10 @@ const outerStyle = { position: 'relative' }; -const inputStyle = { - boxSizing: 'border-box', - display: 'block', - width: '100%', - border: 'none', - padding: '10px', - paddingRight: '30px', - fontFamily: 'inherit', - background: '#282c37', - color: '#9baec8', - fontSize: '14px', - margin: '0' -}; - const iconStyle = { position: 'absolute', top: '18px', right: '20px', - color: '#9baec8', fontSize: '18px', pointerEvents: 'none' }; @@ -66,7 +51,8 @@ const Search = React.createClass({ onChange: React.PropTypes.func.isRequired, onClear: React.PropTypes.func.isRequired, onFetch: React.PropTypes.func.isRequired, - onReset: React.PropTypes.func.isRequired + onReset: React.PropTypes.func.isRequired, + intl: React.PropTypes.object.isRequired }, mixins: [PureRenderMixin], @@ -102,11 +88,11 @@ const Search = React.createClass({ placeholder: this.props.intl.formatMessage(messages.placeholder), value: this.props.value, onChange: this.onChange, - style: inputStyle + className: 'search__input' }; return ( - <div style={outerStyle}> + <div className='search' style={outerStyle}> <Autosuggest multiSection={true} suggestions={this.props.suggestions} diff --git a/app/assets/javascripts/components/features/getting_started/index.jsx b/app/assets/javascripts/components/features/getting_started/index.jsx @@ -44,7 +44,7 @@ const GettingStarted = ({ intl, me }) => { <p><FormattedMessage id='getting_started.about_addressing' defaultMessage='You can follow people if you know their username and the domain they are on by entering an e-mail-esque address into the form at the top of the sidebar.' /></p> <p><FormattedMessage id='getting_started.about_shortcuts' defaultMessage='If the target user is on the same domain as you, just the username will work. The same rule applies to mentioning people in statuses.' /></p> <p><FormattedMessage id='getting_started.about_developer' defaultMessage='The developer of this project can be followed as Gargron@mastodon.social' /></p> - <p><FormattedMessage id='getting_started.open_source_notice' defaultMessage='Mastodon is open source software. You can contribute or report issues on github at {github}' values={{ github: <a style={{ color: '#616b86'}} href="https://github.com/tootsuite/mastodon">tootsuite/mastodon</a> }} /></p> + <p><FormattedMessage id='getting_started.open_source_notice' defaultMessage='Mastodon is open source software. You can contribute or report issues on github at {github}' values={{ github: <a href="https://github.com/tootsuite/mastodon">tootsuite/mastodon</a> }} /></p> </div> </div> </Column> diff --git a/app/assets/javascripts/components/features/status/components/action_bar.jsx b/app/assets/javascripts/components/features/status/components/action_bar.jsx @@ -25,7 +25,8 @@ const ActionBar = React.createClass({ onFavourite: React.PropTypes.func.isRequired, onDelete: React.PropTypes.func.isRequired, onMention: React.PropTypes.func.isRequired, - me: React.PropTypes.number.isRequired + me: React.PropTypes.number.isRequired, + intl: React.PropTypes.object.isRequired }, mixins: [PureRenderMixin], @@ -62,7 +63,7 @@ const ActionBar = React.createClass({ } return ( - <div style={{ background: '#2f3441', display: 'flex', flexDirection: 'row', borderTop: '1px solid #363c4b', borderBottom: '1px solid #363c4b', padding: '10px 0' }}> + <div className='detailed-status__action-bar'> <div style={{ flex: '1 1 auto', textAlign: 'center' }}><IconButton title={intl.formatMessage(messages.reply)} icon='reply' onClick={this.handleReplyClick} /></div> <div style={{ flex: '1 1 auto', textAlign: 'center' }}><IconButton disabled={status.get('visibility') === 'private'} active={status.get('reblogged')} title={intl.formatMessage(messages.reblog)} icon={status.get('visibility') === 'private' ? 'lock' : 'retweet'} onClick={this.handleReblogClick} /></div> <div style={{ flex: '1 1 auto', textAlign: 'center' }}><IconButton animate={true} active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} activeStyle={{ color: '#ca8f04' }} /></div> diff --git a/app/assets/javascripts/components/features/ui/components/column.jsx b/app/assets/javascripts/components/features/ui/components/column.jsx @@ -29,13 +29,6 @@ const scrollTop = (node) => { }; }; -const style = { - boxSizing: 'border-box', - background: '#282c37', - display: 'flex', - flexDirection: 'column' -}; - const Column = React.createClass({ propTypes: { @@ -67,7 +60,7 @@ const Column = React.createClass({ } return ( - <div className='column' style={style} onWheel={this.handleWheel}> + <div className='column' onWheel={this.handleWheel}> {header} {children} </div> diff --git a/app/assets/javascripts/components/features/ui/components/column_header.jsx b/app/assets/javascripts/components/features/ui/components/column_header.jsx @@ -22,7 +22,7 @@ const ColumnHeader = React.createClass({ } return ( - <div onClick={this.handleClick} style={{ padding: '15px', fontSize: '16px', background: '#2f3441', flex: '0 0 auto', cursor: 'pointer' }}> + <div className='column-header' onClick={this.handleClick}> {icon} {this.props.type} </div> diff --git a/app/assets/javascripts/components/features/ui/components/tabs_bar.jsx b/app/assets/javascripts/components/features/ui/components/tabs_bar.jsx @@ -1,36 +1,13 @@ import { Link } from 'react-router'; import { FormattedMessage } from 'react-intl'; -const outerStyle = { - background: '#373b4a', - flex: '0 0 auto', - overflowY: 'auto' -}; - -const tabStyle = { - display: 'block', - flex: '1 1 auto', - padding: '10px 5px', - color: '#fff', - textDecoration: 'none', - textAlign: 'center', - fontSize: '12px', - fontWeight: '500', - borderBottom: '2px solid #373b4a' -}; - -const tabActiveStyle = { - borderBottom: '2px solid #2b90d9', - color: '#2b90d9' -}; - const TabsBar = () => { return ( - <div className='tabs-bar' style={outerStyle}> - <Link style={tabStyle} activeStyle={tabActiveStyle} to='/statuses/new'><i className='fa fa-fw fa-pencil' /> <FormattedMessage id='tabs_bar.compose' defaultMessage='Compose' /></Link> - <Link style={tabStyle} activeStyle={tabActiveStyle} to='/timelines/home'><i className='fa fa-fw fa-home' /> <FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></Link> - <Link style={tabStyle} activeStyle={tabActiveStyle} to='/notifications'><i className='fa fa-fw fa-bell' /> <FormattedMessage id='tabs_bar.notifications' defaultMessage='Notifications' /></Link> - <Link style={{ ...tabStyle, flexGrow: '0', flexBasis: '30px' }} activeStyle={tabActiveStyle} to='/getting-started'><i className='fa fa-fw fa-bars' /></Link> + <div className='tabs-bar'> + <Link className='tabs-bar__link' activeClassName='active' to='/statuses/new'><i className='fa fa-fw fa-pencil' /> <FormattedMessage id='tabs_bar.compose' defaultMessage='Compose' /></Link> + <Link className='tabs-bar__link' activeClassName='active' to='/timelines/home'><i className='fa fa-fw fa-home' /> <FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></Link> + <Link className='tabs-bar__link' activeClassName='active' to='/notifications'><i className='fa fa-fw fa-bell' /> <FormattedMessage id='tabs_bar.notifications' defaultMessage='Notifications' /></Link> + <Link className='tabs-bar__link' activeClassName='active' style={{ flexGrow: '0', flexBasis: '30px' }} to='/getting-started'><i className='fa fa-fw fa-bars' /></Link> </div> ); }; diff --git a/app/assets/javascripts/components/features/ui/index.jsx b/app/assets/javascripts/components/features/ui/index.jsx @@ -89,7 +89,7 @@ const UI = React.createClass({ } return ( - <div style={{ flex: '0 0 auto', display: 'flex', flexDirection: 'column', width: '100%', height: '100%', background: '#1a1c23' }}> + <div className='ui'> <TabsBar /> {mountedColumns} diff --git a/app/assets/stylesheets/components.scss b/app/assets/stylesheets/components.scss @@ -77,6 +77,25 @@ color: $color1; } +.compose-form__label { + display: block; + line-height: 24px; + vertical-align: middle; + + &.with-border { + border-top: 1px solid $color1; + padding-top: 10px; + } + + .compose-form__label__text { + display: inline-block; + vertical-align: middle; + margin-bottom: 14px; + margin-left: 8px; + color: $color3; + } +} + .compose-form__textarea, .follow-form__input { background: $color5; @@ -98,6 +117,15 @@ } } +.reply-indicator { + background: $color3; + padding: 10px; + + .reply-indicator__display-name { + color: $color1; + } +} + .status__content, .reply-indicator__content { font-size: 15px; line-height: 20px; @@ -156,6 +184,47 @@ } } +a.status__content__spoiler-link { + display: inline-block; + border-radius: 2px; + color: lighten($color1, 6%); + font-weight: 500; + font-size: 11px; + padding: 0px 6px; + text-transform: uppercase; + line-height: inherit; +} + +.status { + padding: 8px 10px; + padding-left: 68px; + position: relative; + min-height: 48px; + border-bottom: 1px solid lighten($color1, 6%); + cursor: default; + + .status__relative-time { + color: lighten($color1, 26%); + } + + .status__display-name { + color: lighten($color1, 26%); + } +} + +.status__prepend { + margin-left: 68px; + color: lighten($color1, 26%); + padding: 8px 0; + padding-bottom: 2px; + font-size: 14px; + position: relative; + + .status__display-name strong { + color: lighten($color1, 26%); + } +} + .detailed-status { .status__content { font-size: 19px; @@ -168,6 +237,15 @@ } } +.detailed-status__action-bar { + background: lighten($color1, 4%); + display: flex; + flex-direction: row; + border-top: 1px solid lighten($color1, 6%); + border-bottom: 1px solid lighten($color1, 6%); + padding: 10px 0; +} + .reply-indicator__content { color: $color1; font-size: 14px; @@ -177,6 +255,45 @@ } } +.account { + padding: 10px; + border-bottom: 1px solid lighten($color1, 6%); + + .account__display-name { + flex: 1 1 auto; + display: block; + color: $color3; + overflow: hidden; + text-decoration: none; + font-size: 14px; + } +} + +.account__header { + flex: 0 0 auto; + background: lighten($color1, 4%); + text-align: center; + background-size: cover; + background-position: center; + position: relative; + + & > div { + background: rgba(lighten($color1, 4%), 0.9); + } + + .account__header__content { + color: $color2; + } + + .account__header__display-name { + color: $color5; + } + + .account__header__username { + color: $color4; + } +} + .account__header__content { word-wrap: break-word; font-weight: 400; @@ -207,6 +324,37 @@ } } +.account__action-bar { + border-top: 1px solid lighten($color1, 6%); + border-bottom: 1px solid lighten($color1, 6%); + line-height: 36px; + overflow: hidden; + flex: 0 0 auto; + display: flex; +} + +.account__action-bar__tab { + text-decoration: none; + overflow: hidden; + width: 80px; + border-left: 1px solid lighten($color1, 6%); + padding: 10px 5px; + + & > span { + display: block; + text-transform: uppercase; + font-size: 11px; + color: $color3; + } + + strong { + display: block; + font-size: 15px; + font-weight: 500; + color: $color5; + } +} + .status__display-name, .status__relative-time, .detailed-status__display-name, .detailed-status__datetime, .detailed-status__application, .account__display-name { text-decoration: none; } @@ -298,6 +446,18 @@ display: block; } +.navigation-bar { + padding: 10px; + display: flex; + flex-shrink: 0; + cursor: default; + color: $color3; + + strong { + color: $color5; + } +} + .dropdown { display: inline-block; } @@ -381,10 +541,39 @@ .column { width: 330px; position: relative; + box-sizing: border-box; + background: $color1; + display: flex; + flex-direction: column; +} + +.ui { + flex: 0 0 auto; + display: flex; + flex-direction: column; + width: 100%; + height: 100%; + background: darken($color1, 7%); } .drawer { width: 280px; + box-sizing: border-box; + display: flex; + flex-direction: column; + overflow-y: hidden; +} + +.drawer__tab { + display: block; + flex: 1 1 auto; + padding: 15px; + padding-bottom: 13px; + color: $color3; + text-decoration: none; + text-align: center; + font-size: 16px; + border-bottom: 2px solid transparent; } @media screen and (min-width: 2560px) { @@ -402,6 +591,12 @@ .drawer__inner { background: linear-gradient(rgba(lighten($color1, 13%), 1), rgba(lighten($color1, 13%), 0.65)); + box-sizing: border-box; + padding: 0; + display: flex; + flex-direction: column; + overflow-y: auto; + flex-grow: 1; } .drawer__header { @@ -451,6 +646,26 @@ .tabs-bar { display: flex; + background: lighten($color1, 6%); + flex: 0 0 auto; + overflow-y: auto; +} + +.tabs-bar__link { + display: block; + flex: 1 1 auto; + padding: 10px 5px; + color: $color5; + text-decoration: none; + text-align: center; + font-size:12px; + font-weight: 500; + border-bottom: 2px solid lighten($color1, 6%); + + &.active { + border-bottom: 2px solid $color4; + color: $color4; + } } @media screen and (min-width: 360px) { @@ -516,6 +731,13 @@ } .column-back-button { + padding: 15px; + font-size: 16px; + background: lighten($color1, 4%); + flex: 0 0 auto; + cursor: pointer; + color: $color4; + &:hover { text-decoration: underline; } @@ -699,6 +921,10 @@ p { color: $color2; } + + a { + color: lighten($color1, 26%); + } } .dropdown__content.dropdown__left { @@ -748,7 +974,49 @@ button.active i.fa-retweet { } .load-more { + display: block; + color: lighten($color1, 26%); + text-align: center; + padding: 15px; + text-decoration: none; + &:hover { background: lighten($color1, 6%); } } + +.missing-indicator { + text-align: center; + font-size: 16px; + font-weight: 500; + color: lighten($color1, 26%); + padding-top: 120px; +} + +.column-header { + padding: 15px; + font-size: 16px; + background: lighten($color1, 4%); + flex: 0 0 auto; + cursor: pointer; +} + +.search { + .fa { + color: $color3; + } +} + +.search__input { + box-sizing: border-box; + display: block; + width: 100%; + border: none; + padding: 10px; + padding-right: 30px; + font-family: inherit; + background: $color1; + color: $color3; + font-size: 14px; + margin: 0; +}