Replace inline styles with CSS classes (BEM) (#2338)
* fix(classnames): Status icon style classnames Take out inline css and put into classnames for the following components: account, avatar, icon button, status action bar, notification. * fix(status): Move styles from inline to classes for statuses Move styles to classnames in components.scss for the following components: display name media gallery status status content video player * fix(classnames): Add classnames to rest of components Take out inline styles and apply them to classnames in the sass for the following components: button column back button slim column back button collapsable column dropdown menu loading indicator status list * fix(classnames): Remove all non-dynamic inline styles Components affected: autosuggested permalink action bar header character counter compose form emoji dropdown privacy dropdown reply indicator upload form account auth followers getting started column settings mutes settings reblogs status checkbox report action bar status card boost modal media modal video modal * fix(permalink): Do not lose classname * fix(tests): Add space back in display name * fix(status__wrapper): Remove duplicate css name Remove incorrect style attribute. Remove style attribute all together. Cursor defaults to "auto" when not specified as 'default'. * fix(nl): do not lose translations
This commit is contained in:
parent
532bec6e56
commit
cca41ea544
@ -14,11 +14,6 @@ const messages = defineMessages({
|
|||||||
unmute: { id: 'account.unmute', defaultMessage: 'Unmute' }
|
unmute: { id: 'account.unmute', defaultMessage: 'Unmute' }
|
||||||
});
|
});
|
||||||
|
|
||||||
const buttonsStyle = {
|
|
||||||
padding: '10px',
|
|
||||||
height: '18px'
|
|
||||||
};
|
|
||||||
|
|
||||||
class Account extends React.PureComponent {
|
class Account extends React.PureComponent {
|
||||||
|
|
||||||
constructor (props, context) {
|
constructor (props, context) {
|
||||||
@ -68,13 +63,13 @@ class Account extends React.PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='account'>
|
<div className='account'>
|
||||||
<div style={{ display: 'flex' }}>
|
<div className='account__wrapper'>
|
||||||
<Permalink key={account.get('id')} 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')} staticSrc={account.get('avatar_static')} size={36} /></div>
|
<div className='account__avatar-wrapper'><Avatar src={account.get('avatar')} staticSrc={account.get('avatar_static')} size={36} /></div>
|
||||||
<DisplayName account={account} />
|
<DisplayName account={account} />
|
||||||
</Permalink>
|
</Permalink>
|
||||||
|
|
||||||
<div style={buttonsStyle}>
|
<div className='account__relationship'>
|
||||||
{buttons}
|
{buttons}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -150,7 +150,6 @@ class AutosuggestTextarea extends React.Component {
|
|||||||
render () {
|
render () {
|
||||||
const { value, suggestions, disabled, placeholder, onKeyUp } = this.props;
|
const { value, suggestions, disabled, placeholder, onKeyUp } = this.props;
|
||||||
const { suggestionsHidden, selectedSuggestion } = this.state;
|
const { suggestionsHidden, selectedSuggestion } = this.state;
|
||||||
const className = 'autosuggest-textarea__textarea';
|
|
||||||
const style = { direction: 'ltr' };
|
const style = { direction: 'ltr' };
|
||||||
|
|
||||||
if (isRtl(value)) {
|
if (isRtl(value)) {
|
||||||
@ -161,7 +160,7 @@ class AutosuggestTextarea extends React.Component {
|
|||||||
<div className='autosuggest-textarea'>
|
<div className='autosuggest-textarea'>
|
||||||
<textarea
|
<textarea
|
||||||
ref={this.setTextarea}
|
ref={this.setTextarea}
|
||||||
className={className}
|
className='autosuggest-textarea__textarea'
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
|
@ -38,7 +38,7 @@ class Avatar extends React.PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className='avatar'
|
className='account__avatar'
|
||||||
onMouseEnter={this.handleMouseEnter}
|
onMouseEnter={this.handleMouseEnter}
|
||||||
onMouseLeave={this.handleMouseLeave}
|
onMouseLeave={this.handleMouseLeave}
|
||||||
style={style}
|
style={style}
|
||||||
|
@ -15,25 +15,11 @@ class Button extends React.PureComponent {
|
|||||||
|
|
||||||
render () {
|
render () {
|
||||||
const style = {
|
const style = {
|
||||||
fontFamily: 'inherit',
|
|
||||||
display: this.props.block ? 'block' : 'inline-block',
|
display: this.props.block ? 'block' : 'inline-block',
|
||||||
width: this.props.block ? '100%' : 'auto',
|
width: this.props.block ? '100%' : 'auto',
|
||||||
position: 'relative',
|
|
||||||
boxSizing: 'border-box',
|
|
||||||
textAlign: 'center',
|
|
||||||
border: '10px none',
|
|
||||||
fontSize: '14px',
|
|
||||||
fontWeight: '500',
|
|
||||||
letterSpacing: '0',
|
|
||||||
padding: `0 ${this.props.size / 2.25}px`,
|
padding: `0 ${this.props.size / 2.25}px`,
|
||||||
height: `${this.props.size}px`,
|
height: `${this.props.size}px`,
|
||||||
cursor: 'pointer',
|
lineHeight: `${this.props.size}px`
|
||||||
lineHeight: `${this.props.size}px`,
|
|
||||||
borderRadius: '4px',
|
|
||||||
textDecoration: 'none',
|
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
textOverflow: 'ellipsis',
|
|
||||||
overflow: 'hidden'
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
const iconStyle = {
|
|
||||||
display: 'inline-block',
|
|
||||||
marginRight: '5px'
|
|
||||||
};
|
|
||||||
|
|
||||||
class ColumnBackButton extends React.PureComponent {
|
class ColumnBackButton extends React.PureComponent {
|
||||||
|
|
||||||
constructor (props, context) {
|
constructor (props, context) {
|
||||||
@ -21,7 +16,7 @@ class ColumnBackButton extends React.PureComponent {
|
|||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div role='button' tabIndex='0' onClick={this.handleClick} className='column-back-button'>
|
<div role='button' tabIndex='0' onClick={this.handleClick} className='column-back-button'>
|
||||||
<i className='fa fa-fw fa-chevron-left' style={iconStyle} />
|
<i className='fa fa-fw fa-chevron-left column-back-button__icon'/>
|
||||||
<FormattedMessage id='column_back_button.label' defaultMessage='Back' />
|
<FormattedMessage id='column_back_button.label' defaultMessage='Back' />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,21 +1,6 @@
|
|||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
const outerStyle = {
|
|
||||||
position: 'absolute',
|
|
||||||
right: '0',
|
|
||||||
top: '-48px',
|
|
||||||
padding: '15px',
|
|
||||||
fontSize: '16px',
|
|
||||||
flex: '0 0 auto',
|
|
||||||
cursor: 'pointer'
|
|
||||||
};
|
|
||||||
|
|
||||||
const iconStyle = {
|
|
||||||
display: 'inline-block',
|
|
||||||
marginRight: '5px'
|
|
||||||
};
|
|
||||||
|
|
||||||
class ColumnBackButtonSlim extends React.PureComponent {
|
class ColumnBackButtonSlim extends React.PureComponent {
|
||||||
|
|
||||||
constructor (props, context) {
|
constructor (props, context) {
|
||||||
@ -29,15 +14,14 @@ class ColumnBackButtonSlim extends React.PureComponent {
|
|||||||
|
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div style={{ position: 'relative' }}>
|
<div className='column-back-button--slim'>
|
||||||
<div role='button' tabIndex='0' style={outerStyle} onClick={this.handleClick} className='column-back-button'>
|
<div className='column-back-button--slim-button' role='button' tabIndex='0' onClick={this.handleClick} className='column-back-button'>
|
||||||
<i className='fa fa-fw fa-chevron-left' style={iconStyle} />
|
<i className='fa fa-fw fa-chevron-left column-back-button__icon' />
|
||||||
<FormattedMessage id='column_back_button.label' defaultMessage='Back' />
|
<FormattedMessage id='column_back_button.label' defaultMessage='Back' />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnBackButtonSlim.contextTypes = {
|
ColumnBackButtonSlim.contextTypes = {
|
||||||
|
@ -1,16 +1,6 @@
|
|||||||
import { Motion, spring } from 'react-motion';
|
import { Motion, spring } from 'react-motion';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
const iconStyle = {
|
|
||||||
fontSize: '16px',
|
|
||||||
padding: '15px',
|
|
||||||
position: 'absolute',
|
|
||||||
right: '0',
|
|
||||||
top: '-48px',
|
|
||||||
cursor: 'pointer',
|
|
||||||
zIndex: '3'
|
|
||||||
};
|
|
||||||
|
|
||||||
class ColumnCollapsable extends React.PureComponent {
|
class ColumnCollapsable extends React.PureComponent {
|
||||||
|
|
||||||
constructor (props, context) {
|
constructor (props, context) {
|
||||||
@ -38,8 +28,8 @@ class ColumnCollapsable extends React.PureComponent {
|
|||||||
const collapsedClassName = collapsed ? 'collapsable-collapsed' : 'collapsable';
|
const collapsedClassName = collapsed ? 'collapsable-collapsed' : 'collapsable';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ position: 'relative' }}>
|
<div className='column-collapsable'>
|
||||||
<div role='button' tabIndex='0' title={`${title}`} style={{...iconStyle }} className={`column-icon ${collapsedClassName}`} onClick={this.handleToggleCollapsed}>
|
<div role='button' tabIndex='0' title={`${title}`} className={`column-icon ${collapsedClassName}`} onClick={this.handleToggleCollapsed}>
|
||||||
<i className={`fa fa-${icon}`} />
|
<i className={`fa fa-${icon}`} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@ class DisplayName extends React.PureComponent {
|
|||||||
const displayNameHTML = { __html: emojify(escapeTextContentForBrowser(displayName)) };
|
const displayNameHTML = { __html: emojify(escapeTextContentForBrowser(displayName)) };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span style={{ display: 'block', maxWidth: '100%', overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis' }} className='display-name'>
|
<span className='display-name'>
|
||||||
<strong style={{ fontWeight: '500' }} dangerouslySetInnerHTML={displayNameHTML} /> <span style={{ fontSize: '14px' }}>@{this.props.account.get('acct')}</span>
|
<strong className='display-name__html' dangerouslySetInnerHTML={displayNameHTML} /> <span className='display-name__account'>@{this.props.account.get('acct')}</span>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -28,14 +28,14 @@ class DropdownMenu extends React.PureComponent {
|
|||||||
|
|
||||||
renderItem (item, i) {
|
renderItem (item, i) {
|
||||||
if (item === null) {
|
if (item === null) {
|
||||||
return <li key={i} className='dropdown__sep' />;
|
return <li key={ 'sep' + i } className='dropdown__sep' />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { text, action, href = '#' } = item;
|
const { text, action, href = '#' } = item;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li key={i}>
|
<li className='dropdown__content-list-item' key={ text + i }>
|
||||||
<a href={href} target='_blank' rel='noopener' onClick={this.handleClick.bind(this, i)}>
|
<a href={href} target='_blank' rel='noopener' onClick={this.handleClick.bind(this, i)} className='dropdown__content-list-link'>
|
||||||
{text}
|
{text}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@ -49,11 +49,11 @@ class DropdownMenu extends React.PureComponent {
|
|||||||
return (
|
return (
|
||||||
<Dropdown ref={this.setRef}>
|
<Dropdown ref={this.setRef}>
|
||||||
<DropdownTrigger className='icon-button' style={{ fontSize: `${size}px`, width: `${size}px`, lineHeight: `${size}px` }}>
|
<DropdownTrigger className='icon-button' style={{ fontSize: `${size}px`, width: `${size}px`, lineHeight: `${size}px` }}>
|
||||||
<i className={`fa fa-fw fa-${icon}`} style={{ verticalAlign: 'middle' }} />
|
<i className={ `fa fa-fw fa-${icon} dropdown__icon` } />
|
||||||
</DropdownTrigger>
|
</DropdownTrigger>
|
||||||
|
|
||||||
<DropdownContent className={directionClass} style={{ lineHeight: '18px', textAlign: 'left' }}>
|
<DropdownContent className={directionClass}>
|
||||||
<ul>
|
<ul className='dropdown__content-list'>
|
||||||
{items.map(this.renderItem)}
|
{items.map(this.renderItem)}
|
||||||
</ul>
|
</ul>
|
||||||
</DropdownContent>
|
</DropdownContent>
|
||||||
|
@ -47,6 +47,10 @@ class IconButton extends React.PureComponent {
|
|||||||
classes.push('overlayed');
|
classes.push('overlayed');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.props.className) {
|
||||||
|
classes.push(this.props.className)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Motion defaultStyle={{ rotate: this.props.active ? -360 : 0 }} style={{ rotate: this.props.animate ? spring(this.props.active ? -360 : 0, { stiffness: 120, damping: 7 }) : 0 }}>
|
<Motion defaultStyle={{ rotate: this.props.active ? -360 : 0 }} style={{ rotate: this.props.animate ? spring(this.props.active ? -360 : 0, { stiffness: 120, damping: 7 }) : 0 }}>
|
||||||
{({ rotate }) =>
|
{({ rotate }) =>
|
||||||
@ -66,6 +70,7 @@ class IconButton extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IconButton.propTypes = {
|
IconButton.propTypes = {
|
||||||
|
className: PropTypes.string,
|
||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string.isRequired,
|
||||||
icon: PropTypes.string.isRequired,
|
icon: PropTypes.string.isRequired,
|
||||||
onClick: PropTypes.func,
|
onClick: PropTypes.func,
|
||||||
|
@ -1,14 +1,7 @@
|
|||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
const style = {
|
|
||||||
textAlign: 'center',
|
|
||||||
fontSize: '16px',
|
|
||||||
fontWeight: '500',
|
|
||||||
paddingTop: '120px'
|
|
||||||
};
|
|
||||||
|
|
||||||
const LoadingIndicator = () => (
|
const LoadingIndicator = () => (
|
||||||
<div className='loading-indicator' style={style}>
|
<div className='loading-indicator'>
|
||||||
<FormattedMessage id='loading_indicator.label' defaultMessage='Loading...' />
|
<FormattedMessage id='loading_indicator.label' defaultMessage='Loading...' />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -8,72 +8,7 @@ const messages = defineMessages({
|
|||||||
toggle_visible: { id: 'media_gallery.toggle_visible', defaultMessage: 'Toggle visibility' }
|
toggle_visible: { id: 'media_gallery.toggle_visible', defaultMessage: 'Toggle visibility' }
|
||||||
});
|
});
|
||||||
|
|
||||||
const outerStyle = {
|
|
||||||
marginTop: '8px',
|
|
||||||
overflow: 'hidden',
|
|
||||||
width: '100%',
|
|
||||||
boxSizing: 'border-box',
|
|
||||||
position: 'relative'
|
|
||||||
};
|
|
||||||
|
|
||||||
const spoilerStyle = {
|
|
||||||
textAlign: 'center',
|
|
||||||
height: '100%',
|
|
||||||
cursor: 'pointer',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
flexDirection: 'column'
|
|
||||||
};
|
|
||||||
|
|
||||||
const spoilerSpanStyle = {
|
|
||||||
display: 'block',
|
|
||||||
fontSize: '14px',
|
|
||||||
};
|
|
||||||
|
|
||||||
const spoilerSubSpanStyle = {
|
|
||||||
display: 'block',
|
|
||||||
fontSize: '11px',
|
|
||||||
fontWeight: '500'
|
|
||||||
};
|
|
||||||
|
|
||||||
const spoilerButtonStyle = {
|
|
||||||
position: 'absolute',
|
|
||||||
top: '4px',
|
|
||||||
left: '4px',
|
|
||||||
zIndex: '100'
|
|
||||||
};
|
|
||||||
|
|
||||||
const itemStyle = {
|
|
||||||
boxSizing: 'border-box',
|
|
||||||
position: 'relative',
|
|
||||||
float: 'left',
|
|
||||||
border: 'none',
|
|
||||||
display: 'block'
|
|
||||||
};
|
|
||||||
|
|
||||||
const thumbStyle = {
|
|
||||||
display: 'block',
|
|
||||||
width: '100%',
|
|
||||||
height: '100%',
|
|
||||||
textDecoration: 'none',
|
|
||||||
backgroundSize: 'cover',
|
|
||||||
cursor: 'zoom-in'
|
|
||||||
};
|
|
||||||
|
|
||||||
const gifvThumbStyle = {
|
|
||||||
position: 'relative',
|
|
||||||
zIndex: '1',
|
|
||||||
width: '100%',
|
|
||||||
height: '100%',
|
|
||||||
objectFit: 'cover',
|
|
||||||
top: '50%',
|
|
||||||
transform: 'translateY(-50%)',
|
|
||||||
cursor: 'zoom-in'
|
|
||||||
};
|
|
||||||
|
|
||||||
class Item extends React.PureComponent {
|
class Item extends React.PureComponent {
|
||||||
|
|
||||||
constructor (props, context) {
|
constructor (props, context) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
this.handleClick = this.handleClick.bind(this);
|
this.handleClick = this.handleClick.bind(this);
|
||||||
@ -147,24 +82,26 @@ class Item extends React.PureComponent {
|
|||||||
if (attachment.get('type') === 'image') {
|
if (attachment.get('type') === 'image') {
|
||||||
thumbnail = (
|
thumbnail = (
|
||||||
<a
|
<a
|
||||||
href={attachment.get('remote_url') ? attachment.get('remote_url') : attachment.get('url')}
|
className='media-gallery__item-thumbnail'
|
||||||
|
href={attachment.get('remote_url') || attachment.get('url')}
|
||||||
onClick={this.handleClick}
|
onClick={this.handleClick}
|
||||||
target='_blank'
|
target='_blank'
|
||||||
style={{ background: `url(${attachment.get('preview_url')}) no-repeat center`, ...thumbStyle }}
|
style={{ background: `url(${attachment.get('preview_url')}) no-repeat center`}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else if (attachment.get('type') === 'gifv') {
|
} else if (attachment.get('type') === 'gifv') {
|
||||||
const autoPlay = !isIOS() && this.props.autoPlayGif;
|
const autoPlay = !isIOS() && this.props.autoPlayGif;
|
||||||
|
|
||||||
thumbnail = (
|
thumbnail = (
|
||||||
<div style={{ position: 'relative', width: '100%', height: '100%', overflow: 'hidden' }} className={`media-gallery__gifv ${autoPlay ? 'autoplay' : ''}`}>
|
<div className={`media-gallery__gifv ${autoPlay ? 'autoplay' : ''}`}>
|
||||||
<video
|
<video
|
||||||
|
className='media-gallery__item-gifv-thumbnail'
|
||||||
|
role='application'
|
||||||
src={attachment.get('url')}
|
src={attachment.get('url')}
|
||||||
onClick={this.handleClick}
|
onClick={this.handleClick}
|
||||||
autoPlay={autoPlay}
|
autoPlay={autoPlay}
|
||||||
loop={true}
|
loop={true}
|
||||||
muted={true}
|
muted={true}
|
||||||
style={gifvThumbStyle}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<span className='media-gallery__gifv__label'>GIF</span>
|
<span className='media-gallery__gifv__label'>GIF</span>
|
||||||
@ -173,7 +110,7 @@ class Item extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={attachment.get('id')} style={{ ...itemStyle, left: left, top: top, right: right, bottom: bottom, width: `${width}%`, height: `${height}%` }}>
|
<div className='media-gallery__item' key={attachment.get('id')} style={{ left: left, top: top, right: right, bottom: bottom, width: `${width}%`, height: `${height}%` }}>
|
||||||
{thumbnail}
|
{thumbnail}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -223,9 +160,9 @@ class MediaGallery extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
children = (
|
children = (
|
||||||
<div role='button' tabIndex='0' style={spoilerStyle} className='media-spoiler' onClick={this.handleOpen}>
|
<div role='button' tabIndex='0' className='media-spoiler' onClick={this.handleOpen}>
|
||||||
<span style={spoilerSpanStyle}>{warning}</span>
|
<span className='media-spoiler__warning'>{warning}</span>
|
||||||
<span style={spoilerSubSpanStyle}><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span>
|
<span className='media-spoiler__trigger'><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -234,8 +171,8 @@ class MediaGallery extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ ...outerStyle, height: `${this.props.height}px` }}>
|
<div className='media-gallery' style={{ height: `${this.props.height}px` }}>
|
||||||
<div style={{ ...spoilerButtonStyle, display: !this.state.visible ? 'none' : 'block' }}>
|
<div className='spoiler-button' style={{ display: !this.state.visible ? 'none' : 'block' }}>
|
||||||
<IconButton title={intl.formatMessage(messages.toggle_visible)} icon={this.state.visible ? 'eye' : 'eye-slash'} overlay onClick={this.handleOpen} />
|
<IconButton title={intl.formatMessage(messages.toggle_visible)} icon={this.state.visible ? 'eye' : 'eye-slash'} overlay onClick={this.handleOpen} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -15,9 +15,9 @@ class Permalink extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { href, children, ...other } = this.props;
|
const { href, children, className, ...other } = this.props;
|
||||||
|
|
||||||
return <a href={href} onClick={this.handleClick} {...other}>{children}</a>;
|
return <a href={href} onClick={this.handleClick} {...other} className={'permalink ' + className}>{children}</a>;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -27,6 +27,7 @@ Permalink.contextTypes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Permalink.propTypes = {
|
Permalink.propTypes = {
|
||||||
|
className: PropTypes.string,
|
||||||
href: PropTypes.string.isRequired,
|
href: PropTypes.string.isRequired,
|
||||||
to: PropTypes.string.isRequired,
|
to: PropTypes.string.isRequired,
|
||||||
children: PropTypes.node
|
children: PropTypes.node
|
||||||
|
@ -50,9 +50,9 @@ class Status extends React.PureComponent {
|
|||||||
const displayNameHTML = { __html: emojify(escapeTextContentForBrowser(displayName)) };
|
const displayNameHTML = { __html: emojify(escapeTextContentForBrowser(displayName)) };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ cursor: 'default' }}>
|
<div className='status__wrapper'>
|
||||||
<div className='status__prepend'>
|
<div className='status__prepend'>
|
||||||
<div style={{ position: 'absolute', 'left': '-26px'}}><i className='fa fa-fw fa-retweet' /></div>
|
<div className='status__prepend-icon-wrapper'><i className='fa fa-fw fa-retweet status__prepend-icon' /></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 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>
|
</div>
|
||||||
|
|
||||||
@ -73,13 +73,13 @@ class Status extends React.PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={this.props.muted ? 'status muted' : 'status'}>
|
<div className={this.props.muted ? 'status muted' : 'status'}>
|
||||||
<div style={{ fontSize: '15px' }}>
|
<div className='status__info'>
|
||||||
<div style={{ float: 'right', fontSize: '14px' }}>
|
<div className='status__info-time'>
|
||||||
<a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener'><RelativeTimestamp timestamp={status.get('created_at')} /></a>
|
<a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener'><RelativeTimestamp timestamp={status.get('created_at')} /></a>
|
||||||
</div>
|
</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' }}>
|
<a onClick={this.handleAccountClick.bind(this, status.getIn(['account', 'id']))} href={status.getIn(['account', 'url'])} className='status__display-name'>
|
||||||
<div className='status__avatar' style={{ position: 'absolute', left: '10px', top: '10px', width: '48px', height: '48px' }}>
|
<div className='status__avatar'>
|
||||||
<Avatar src={status.getIn(['account', 'avatar'])} staticSrc={status.getIn(['account', 'avatar_static'])} size={48} />
|
<Avatar src={status.getIn(['account', 'avatar'])} staticSrc={status.getIn(['account', 'avatar_static'])} size={48} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -100,12 +100,12 @@ class StatusActionBar extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ marginTop: '10px', overflow: 'hidden' }}>
|
<div className='status__action-bar'>
|
||||||
<div style={{ float: 'left', marginRight: '18px'}}><IconButton title={reply_title} icon={reply_icon} onClick={this.handleReplyClick} /></div>
|
<div className='status__action-bar-button-wrapper'><IconButton title={reply_title} icon={reply_icon} onClick={this.handleReplyClick} /></div>
|
||||||
<div style={{ float: 'left', marginRight: '18px'}}><IconButton disabled={status.get('visibility') === 'private' || status.get('visibility') === 'direct'} active={status.get('reblogged')} title={intl.formatMessage(messages.reblog)} icon={reblogIcon} onClick={this.handleReblogClick} /></div>
|
<div className='status__action-bar-button-wrapper'><IconButton disabled={status.get('visibility') === 'private' || status.get('visibility') === 'direct'} active={status.get('reblogged')} title={intl.formatMessage(messages.reblog)} icon={reblogIcon} onClick={this.handleReblogClick} /></div>
|
||||||
<div style={{ float: 'left', marginRight: '18px'}}><IconButton animate={true} active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} activeStyle={{ color: '#ca8f04' }} /></div>
|
<div className='status__action-bar-button-wrapper'><IconButton animate={true} active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} className='star-icon' /></div>
|
||||||
|
|
||||||
<div style={{ width: '18px', height: '18px', float: 'left' }}>
|
<div className='status__action-bar-dropdown'>
|
||||||
<DropdownMenu items={menu} icon='ellipsis-h' size={18} direction="right" />
|
<DropdownMenu items={menu} icon='ellipsis-h' size={18} direction="right" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -112,7 +112,7 @@ class StatusContent extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='status__content' style={{ cursor: 'pointer' }} onMouseDown={this.handleMouseDown} onMouseUp={this.handleMouseUp}>
|
<div className='status__content' onMouseDown={this.handleMouseDown} onMouseUp={this.handleMouseUp}>
|
||||||
<p style={{ marginBottom: hidden && status.get('mentions').size === 0 ? '0px' : '' }} >
|
<p style={{ marginBottom: hidden && status.get('mentions').size === 0 ? '0px' : '' }} >
|
||||||
<span dangerouslySetInnerHTML={spoilerContent} /> <a tabIndex='0' className='status__content__spoiler-link' role='button' onClick={this.handleSpoilerClick}>{toggleText}</a>
|
<span dangerouslySetInnerHTML={spoilerContent} /> <a tabIndex='0' className='status__content__spoiler-link' role='button' onClick={this.handleSpoilerClick}>{toggleText}</a>
|
||||||
</p>
|
</p>
|
||||||
@ -126,7 +126,7 @@ class StatusContent extends React.PureComponent {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className='status__content'
|
className='status__content'
|
||||||
style={{ cursor: 'pointer', ...directionStyle }}
|
style={{ ...directionStyle }}
|
||||||
onMouseDown={this.handleMouseDown}
|
onMouseDown={this.handleMouseDown}
|
||||||
onMouseUp={this.handleMouseUp}
|
onMouseUp={this.handleMouseUp}
|
||||||
dangerouslySetInnerHTML={content}
|
dangerouslySetInnerHTML={content}
|
||||||
@ -135,7 +135,7 @@ class StatusContent extends React.PureComponent {
|
|||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className='status__content'
|
className='status__content status__content--no-action'
|
||||||
style={{ ...directionStyle }}
|
style={{ ...directionStyle }}
|
||||||
dangerouslySetInnerHTML={content}
|
dangerouslySetInnerHTML={content}
|
||||||
/>
|
/>
|
||||||
|
@ -79,7 +79,7 @@ class StatusList extends React.PureComponent {
|
|||||||
<div className='scrollable' ref={this.setRef}>
|
<div className='scrollable' ref={this.setRef}>
|
||||||
{unread}
|
{unread}
|
||||||
|
|
||||||
<div>
|
<div className='status-list'>
|
||||||
{prepend}
|
{prepend}
|
||||||
|
|
||||||
{statusIds.map((statusId) => {
|
{statusIds.map((statusId) => {
|
||||||
|
@ -11,67 +11,6 @@ const messages = defineMessages({
|
|||||||
expand_video: { id: 'video_player.video_error', defaultMessage: 'Video could not be played' }
|
expand_video: { id: 'video_player.video_error', defaultMessage: 'Video could not be played' }
|
||||||
});
|
});
|
||||||
|
|
||||||
const videoStyle = {
|
|
||||||
position: 'relative',
|
|
||||||
zIndex: '1',
|
|
||||||
width: '100%',
|
|
||||||
height: '100%',
|
|
||||||
objectFit: 'cover',
|
|
||||||
top: '50%',
|
|
||||||
transform: 'translateY(-50%)'
|
|
||||||
};
|
|
||||||
|
|
||||||
const muteStyle = {
|
|
||||||
position: 'absolute',
|
|
||||||
top: '4px',
|
|
||||||
right: '4px',
|
|
||||||
color: 'white',
|
|
||||||
textShadow: "0px 1px 1px black, 1px 0px 1px black",
|
|
||||||
opacity: '0.8',
|
|
||||||
zIndex: '5'
|
|
||||||
};
|
|
||||||
|
|
||||||
const coverStyle = {
|
|
||||||
marginTop: '8px',
|
|
||||||
textAlign: 'center',
|
|
||||||
height: '100%',
|
|
||||||
cursor: 'pointer',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
flexDirection: 'column',
|
|
||||||
position: 'relative'
|
|
||||||
};
|
|
||||||
|
|
||||||
const spoilerSpanStyle = {
|
|
||||||
display: 'block',
|
|
||||||
fontSize: '14px'
|
|
||||||
};
|
|
||||||
|
|
||||||
const spoilerSubSpanStyle = {
|
|
||||||
display: 'block',
|
|
||||||
fontSize: '11px',
|
|
||||||
fontWeight: '500'
|
|
||||||
};
|
|
||||||
|
|
||||||
const spoilerButtonStyle = {
|
|
||||||
position: 'absolute',
|
|
||||||
top: '4px',
|
|
||||||
left: '4px',
|
|
||||||
color: 'white',
|
|
||||||
textShadow: "0px 1px 1px black, 1px 0px 1px black",
|
|
||||||
zIndex: '100'
|
|
||||||
};
|
|
||||||
|
|
||||||
const expandButtonStyle = {
|
|
||||||
position: 'absolute',
|
|
||||||
bottom: '4px',
|
|
||||||
right: '4px',
|
|
||||||
color: 'white',
|
|
||||||
textShadow: "0px 1px 1px black, 1px 0px 1px black",
|
|
||||||
zIndex: '100'
|
|
||||||
};
|
|
||||||
|
|
||||||
class VideoPlayer extends React.PureComponent {
|
class VideoPlayer extends React.PureComponent {
|
||||||
|
|
||||||
constructor (props, context) {
|
constructor (props, context) {
|
||||||
@ -83,6 +22,7 @@ class VideoPlayer extends React.PureComponent {
|
|||||||
hasAudio: true,
|
hasAudio: true,
|
||||||
videoError: false
|
videoError: false
|
||||||
};
|
};
|
||||||
|
|
||||||
this.handleClick = this.handleClick.bind(this);
|
this.handleClick = this.handleClick.bind(this);
|
||||||
this.handleVideoClick = this.handleVideoClick.bind(this);
|
this.handleVideoClick = this.handleVideoClick.bind(this);
|
||||||
this.handleOpen = this.handleOpen.bind(this);
|
this.handleOpen = this.handleOpen.bind(this);
|
||||||
@ -170,13 +110,13 @@ class VideoPlayer extends React.PureComponent {
|
|||||||
const { media, intl, width, height, sensitive, autoplay } = this.props;
|
const { media, intl, width, height, sensitive, autoplay } = this.props;
|
||||||
|
|
||||||
let spoilerButton = (
|
let spoilerButton = (
|
||||||
<div style={{...spoilerButtonStyle, display: !this.state.visible ? 'none' : 'block'}} >
|
<div className='status__video-player-spoiler' style={{ display: !this.state.visible ? 'none' : 'block' }} >
|
||||||
<IconButton overlay title={intl.formatMessage(messages.toggle_visible)} icon={this.state.visible ? 'eye' : 'eye-slash'} onClick={this.handleVisibility} />
|
<IconButton overlay title={intl.formatMessage(messages.toggle_visible)} icon={this.state.visible ? 'eye' : 'eye-slash'} onClick={this.handleVisibility} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
let expandButton = (
|
let expandButton = (
|
||||||
<div style={expandButtonStyle} >
|
<div className='status__video-player-expand'>
|
||||||
<IconButton overlay title={intl.formatMessage(messages.expand_video)} icon='expand' onClick={this.handleExpand} />
|
<IconButton overlay title={intl.formatMessage(messages.expand_video)} icon='expand' onClick={this.handleExpand} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -185,7 +125,7 @@ class VideoPlayer extends React.PureComponent {
|
|||||||
|
|
||||||
if (this.state.hasAudio) {
|
if (this.state.hasAudio) {
|
||||||
muteButton = (
|
muteButton = (
|
||||||
<div style={muteStyle}>
|
<div className='status__video-player-mute'>
|
||||||
<IconButton overlay title={intl.formatMessage(messages.toggle_sound)} icon={this.state.muted ? 'volume-off' : 'volume-up'} onClick={this.handleClick} />
|
<IconButton overlay title={intl.formatMessage(messages.toggle_sound)} icon={this.state.muted ? 'volume-off' : 'volume-up'} onClick={this.handleClick} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -194,18 +134,18 @@ class VideoPlayer extends React.PureComponent {
|
|||||||
if (!this.state.visible) {
|
if (!this.state.visible) {
|
||||||
if (sensitive) {
|
if (sensitive) {
|
||||||
return (
|
return (
|
||||||
<div role='button' tabIndex='0' style={{...coverStyle, width: `${width}px`, height: `${height}px` }} className='media-spoiler' onClick={this.handleVisibility}>
|
<div role='button' tabIndex='0' style={{ width: `${width}px`, height: `${height}px` }} className='media-spoiler' onClick={this.handleVisibility}>
|
||||||
{spoilerButton}
|
{spoilerButton}
|
||||||
<span style={spoilerSpanStyle}><FormattedMessage id='status.sensitive_warning' defaultMessage='Sensitive content' /></span>
|
<span className='media-spoiler__warning'><FormattedMessage id='status.sensitive_warning' defaultMessage='Sensitive content' /></span>
|
||||||
<span style={spoilerSubSpanStyle}><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span>
|
<span className='media-spoiler__trigger'><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<div role='button' tabIndex='0' style={{...coverStyle, width: `${width}px`, height: `${height}px` }} className='media-spoiler' onClick={this.handleVisibility}>
|
<div role='button' tabIndex='0' style={{ width: `${width}px`, height: `${height}px` }} className='media-spoiler' onClick={this.handleVisibility}>
|
||||||
{spoilerButton}
|
{spoilerButton}
|
||||||
<span style={spoilerSpanStyle}><FormattedMessage id='status.media_hidden' defaultMessage='Media hidden' /></span>
|
<span className='media-spoiler__warning'><FormattedMessage id='status.media_hidden' defaultMessage='Media hidden' /></span>
|
||||||
<span style={spoilerSubSpanStyle}><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span>
|
<span className='media-spoiler__trigger'><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -213,27 +153,27 @@ class VideoPlayer extends React.PureComponent {
|
|||||||
|
|
||||||
if (this.state.preview && !autoplay) {
|
if (this.state.preview && !autoplay) {
|
||||||
return (
|
return (
|
||||||
<div role='button' tabIndex='0' style={{ cursor: 'pointer', position: 'relative', marginTop: '8px', width: `${width}px`, height: `${height}px`, background: `url(${media.get('preview_url')}) no-repeat center`, backgroundSize: 'cover' }} onClick={this.handleOpen}>
|
<div role='button' tabIndex='0' className='media-spoiler-video' style={{ width: `${width}px`, height: `${height}px`, background: `url(${media.get('preview_url')}) no-repeat center` }} onClick={this.handleOpen}>
|
||||||
{spoilerButton}
|
{spoilerButton}
|
||||||
<div style={{ position: 'absolute', top: '50%', left: '50%', fontSize: '36px', transform: 'translate(-50%, -50%)', padding: '5px', borderRadius: '100px', color: 'rgba(255, 255, 255, 0.8)' }}><i className='fa fa-play' /></div>
|
<div className='media-spoiler-video-play-icon'><i className='fa fa-play' /></div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.state.videoError) {
|
if (this.state.videoError) {
|
||||||
return (
|
return (
|
||||||
<div style={{...coverStyle, width: `${width}px`, height: `${height}px` }} className='video-error-cover' >
|
<div style={{ width: `${width}px`, height: `${height}px` }} className='video-error-cover' >
|
||||||
<span style={spoilerSpanStyle}><FormattedMessage id='video_player.video_error' defaultMessage='Video could not be played' /></span>
|
<span className='media-spoiler__warning'><FormattedMessage id='video_player.video_error' defaultMessage='Video could not be played' /></span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ cursor: 'default', marginTop: '8px', overflow: 'hidden', width: `${width}px`, height: `${height}px`, boxSizing: 'border-box', background: '#000', position: 'relative' }}>
|
<div className='status__video-player' style={{ width: `${width}px`, height: `${height}px` }}>
|
||||||
{spoilerButton}
|
{spoilerButton}
|
||||||
{muteButton}
|
{muteButton}
|
||||||
{expandButton}
|
{expandButton}
|
||||||
<video role='button' tabIndex='0' ref={this.setRef} src={media.get('url')} autoPlay={!isIOS()} loop={true} muted={this.state.muted} style={videoStyle} onClick={this.handleVideoClick} />
|
<video className='status__video-player-video' role='button' tabIndex='0' ref={this.setRef} src={media.get('url')} autoPlay={!isIOS()} loop={true} muted={this.state.muted} onClick={this.handleVideoClick} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -17,17 +17,6 @@ const messages = defineMessages({
|
|||||||
disclaimer: { id: 'account.disclaimer', defaultMessage: 'This user is from another instance. This number may be larger.' }
|
disclaimer: { id: 'account.disclaimer', defaultMessage: 'This user is from another instance. This number may be larger.' }
|
||||||
});
|
});
|
||||||
|
|
||||||
const outerDropdownStyle = {
|
|
||||||
padding: '10px',
|
|
||||||
flex: '1 1 auto'
|
|
||||||
};
|
|
||||||
|
|
||||||
const outerLinksStyle = {
|
|
||||||
flex: '1 1 auto',
|
|
||||||
display: 'flex',
|
|
||||||
lineHeight: '18px'
|
|
||||||
};
|
|
||||||
|
|
||||||
class ActionBar extends React.PureComponent {
|
class ActionBar extends React.PureComponent {
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
@ -63,11 +52,11 @@ class ActionBar extends React.PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='account__action-bar'>
|
<div className='account__action-bar'>
|
||||||
<div style={outerDropdownStyle}>
|
<div className='account__action-bar-dropdown'>
|
||||||
<DropdownMenu items={menu} icon='bars' size={24} direction="right" />
|
<DropdownMenu items={menu} icon='bars' size={24} direction="right" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={outerLinksStyle}>
|
<div className='account__action-bar-links'>
|
||||||
<Link className='account__action-bar__tab' to={`/accounts/${account.get('id')}`}>
|
<Link className='account__action-bar__tab' to={`/accounts/${account.get('id')}`}>
|
||||||
<span><FormattedMessage id='account.posts' defaultMessage='Posts' /></span>
|
<span><FormattedMessage id='account.posts' defaultMessage='Posts' /></span>
|
||||||
<strong><FormattedNumber value={account.get('statuses_count')} /> {extraInfo}</strong>
|
<strong><FormattedNumber value={account.get('statuses_count')} /> {extraInfo}</strong>
|
||||||
|
@ -56,7 +56,7 @@ class Avatar extends React.PureComponent {
|
|||||||
className='account__header__avatar'
|
className='account__header__avatar'
|
||||||
target='_blank'
|
target='_blank'
|
||||||
rel='noopener'
|
rel='noopener'
|
||||||
style={{ display: 'block', width: '90px', height: '90px', margin: '0 auto', marginBottom: '10px', borderRadius: `${radius}px`, overflow: 'hidden', backgroundSize: '90px 90px', backgroundImage: `url(${autoPlayGif || isHovered ? account.get('avatar') : account.get('avatar_static')})` }}
|
style={{ borderRadius: `${radius}px`, backgroundImage: `url(${autoPlayGif || isHovered ? account.get('avatar') : account.get('avatar_static')})` }}
|
||||||
onMouseOver={this.handleMouseOver}
|
onMouseOver={this.handleMouseOver}
|
||||||
onMouseOut={this.handleMouseOut}
|
onMouseOut={this.handleMouseOut}
|
||||||
onFocus={this.handleMouseOver}
|
onFocus={this.handleMouseOver}
|
||||||
|
@ -44,7 +44,7 @@ class Header extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className='account-timeline__header'>
|
||||||
<InnerHeader
|
<InnerHeader
|
||||||
account={account}
|
account={account}
|
||||||
me={me}
|
me={me}
|
||||||
|
@ -3,8 +3,8 @@ import DisplayName from '../../../components/display_name';
|
|||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
|
|
||||||
const AutosuggestAccount = ({ account }) => (
|
const AutosuggestAccount = ({ account }) => (
|
||||||
<div style={{ overflow: 'hidden' }} className='autosuggest-account'>
|
<div className='autosuggest-account'>
|
||||||
<div style={{ float: 'left', marginRight: '5px' }}><Avatar src={account.get('avatar')} staticSrc={account.get('avatar_static')} size={18} /></div>
|
<div className='autosuggest-account-icon'><Avatar src={account.get('avatar')} staticSrc={account.get('avatar_static')} size={18} /></div>
|
||||||
<DisplayName account={account} />
|
<DisplayName account={account} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -3,7 +3,7 @@ import DisplayName from '../../../components/display_name';
|
|||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
|
|
||||||
const AutosuggestStatus = ({ status }) => (
|
const AutosuggestStatus = ({ status }) => (
|
||||||
<div style={{ overflow: 'hidden' }} className='autosuggest-status'>
|
<div className='autosuggest-status'>
|
||||||
<FormattedMessage id='search.status_by' defaultMessage='Status by {name}' values={{ name: <strong>@{status.getIn(['account', 'acct'])}</strong> }} />
|
<FormattedMessage id='search.status_by' defaultMessage='Status by {name}' values={{ name: <strong>@{status.getIn(['account', 'acct'])}</strong> }} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -4,9 +4,9 @@ class CharacterCounter extends React.PureComponent {
|
|||||||
|
|
||||||
checkRemainingText (diff) {
|
checkRemainingText (diff) {
|
||||||
if (diff <= 0) {
|
if (diff <= 0) {
|
||||||
return <span style={{ fontSize: '16px', cursor: 'default', color: '#ff5050' }}>{diff}</span>;
|
return <span className='character-counter character-counter--over'>{diff}</span>;
|
||||||
}
|
}
|
||||||
return <span style={{ fontSize: '16px', cursor: 'default' }}>{diff}</span>;
|
return <span className='character-counter'>{diff}</span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
@ -137,13 +137,13 @@ class ComposeForm extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.privacy === 'private' || this.props.privacy === 'direct') {
|
if (this.props.privacy === 'private' || this.props.privacy === 'direct') {
|
||||||
publishText = <span><i className='fa fa-lock' /> {intl.formatMessage(messages.publish)}</span>;
|
publishText = <span className='compose-form__publish-private'><i className='fa fa-lock' /> {intl.formatMessage(messages.publish)}</span>;
|
||||||
} else {
|
} else {
|
||||||
publishText = intl.formatMessage(messages.publish) + (this.props.privacy !== 'unlisted' ? '!' : '');
|
publishText = intl.formatMessage(messages.publish) + (this.props.privacy !== 'unlisted' ? '!' : '');
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ padding: '10px' }}>
|
<div className='compose-form'>
|
||||||
<Collapsable isVisible={this.props.spoiler} fullHeight={50}>
|
<Collapsable isVisible={this.props.spoiler} fullHeight={50}>
|
||||||
<div className="spoiler-input">
|
<div className="spoiler-input">
|
||||||
<input placeholder={intl.formatMessage(messages.spoiler_placeholder)} value={this.props.spoiler_text} onChange={this.handleChangeSpoilerText} onKeyDown={this.handleKeyDown} type="text" className="spoiler-input__input" />
|
<input placeholder={intl.formatMessage(messages.spoiler_placeholder)} value={this.props.spoiler_text} onChange={this.handleChangeSpoilerText} onKeyDown={this.handleKeyDown} type="text" className="spoiler-input__input" />
|
||||||
@ -154,7 +154,7 @@ class ComposeForm extends React.PureComponent {
|
|||||||
|
|
||||||
<ReplyIndicatorContainer />
|
<ReplyIndicatorContainer />
|
||||||
|
|
||||||
<div style={{ position: 'relative' }}>
|
<div className='compose-form__autosuggest-wrapper'>
|
||||||
<AutosuggestTextarea
|
<AutosuggestTextarea
|
||||||
ref={this.setAutosuggestTextarea}
|
ref={this.setAutosuggestTextarea}
|
||||||
placeholder={intl.formatMessage(messages.placeholder)}
|
placeholder={intl.formatMessage(messages.placeholder)}
|
||||||
@ -176,7 +176,7 @@ class ComposeForm extends React.PureComponent {
|
|||||||
<UploadFormContainer />
|
<UploadFormContainer />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
<div className='compose-form__buttons-wrapper'>
|
||||||
<div className='compose-form__buttons'>
|
<div className='compose-form__buttons'>
|
||||||
<UploadButtonContainer />
|
<UploadButtonContainer />
|
||||||
<PrivacyDropdownContainer />
|
<PrivacyDropdownContainer />
|
||||||
@ -184,9 +184,9 @@ class ComposeForm extends React.PureComponent {
|
|||||||
<SpoilerButtonContainer />
|
<SpoilerButtonContainer />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ display: 'flex', minWidth: 0 }}>
|
<div className='compose-form__publish'>
|
||||||
<div style={{ paddingTop: '10px', marginRight: '16px', lineHeight: '36px' }}><CharacterCounter max={500} text={text} /></div>
|
<div className='character-counter__wrapper'><CharacterCounter max={500} text={text} /></div>
|
||||||
<div style={{ paddingTop: '10px', overflow: 'hidden' }}><Button text={publishText} onClick={this.handleSubmit} disabled={disabled || text.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "_").length > 500} block /></div>
|
<div className='compose-form__publish-button-wrapper'><Button text={publishText} onClick={this.handleSubmit} disabled={disabled || text.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "_").length > 500} block /></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -22,12 +22,20 @@ const settings = {
|
|||||||
imagePathPNG: '/emoji/'
|
imagePathPNG: '/emoji/'
|
||||||
};
|
};
|
||||||
|
|
||||||
const style = {
|
const dropdownStyle = {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
right: '5px',
|
right: '5px',
|
||||||
top: '5px'
|
top: '5px'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const dropdownTriggerStyle = {
|
||||||
|
display: 'block',
|
||||||
|
fontSize: '24px',
|
||||||
|
lineHeight: '24px',
|
||||||
|
marginLeft: '2px',
|
||||||
|
width: '24px'
|
||||||
|
}
|
||||||
|
|
||||||
class EmojiPickerDropdown extends React.PureComponent {
|
class EmojiPickerDropdown extends React.PureComponent {
|
||||||
|
|
||||||
constructor (props, context) {
|
constructor (props, context) {
|
||||||
@ -84,8 +92,8 @@ class EmojiPickerDropdown extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dropdown ref={this.setRef} style={style}>
|
<Dropdown ref={this.setRef} style={dropdownStyle}>
|
||||||
<DropdownTrigger className='emoji-button' title={intl.formatMessage(messages.emoji)} style={{ fontSize: `24px`, width: `24px`, lineHeight: `24px`, display: 'block', marginLeft: '2px' }}>
|
<DropdownTrigger className='emoji-button' title={intl.formatMessage(messages.emoji)} style={dropdownTriggerStyle}>
|
||||||
<img draggable="false" className="emojione" alt="🙂" src="/emoji/1f602.svg" />
|
<img draggable="false" className="emojione" alt="🙂" src="/emoji/1f602.svg" />
|
||||||
</DropdownTrigger>
|
</DropdownTrigger>
|
||||||
|
|
||||||
|
@ -11,11 +11,11 @@ class NavigationBar extends React.PureComponent {
|
|||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div className='navigation-bar'>
|
<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')} animate size={40} /></Permalink>
|
<Permalink href={this.props.account.get('url')} to={`/accounts/${this.props.account.get('id')}`}><Avatar src={this.props.account.get('avatar')} animate size={40} /></Permalink>
|
||||||
|
|
||||||
<div style={{ flex: '1 1 auto', marginLeft: '8px' }}>
|
<div className='navigation-bar__profile'>
|
||||||
<strong style={{ fontWeight: '500', display: 'block' }}>{this.props.account.get('acct')}</strong>
|
<strong className='navigation-bar__profile-account'>{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>
|
<a href='/settings/profile' className='navigation-bar__profile-edit'><FormattedMessage id='navigation_bar.edit_profile' defaultMessage='Edit profile' /></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -14,11 +14,6 @@ const messages = defineMessages({
|
|||||||
change_privacy: { id: 'privacy.change', defaultMessage: 'Adjust status privacy' }
|
change_privacy: { id: 'privacy.change', defaultMessage: 'Adjust status privacy' }
|
||||||
});
|
});
|
||||||
|
|
||||||
const iconStyle = {
|
|
||||||
lineHeight: '27px',
|
|
||||||
height: null
|
|
||||||
};
|
|
||||||
|
|
||||||
class PrivacyDropdown extends React.PureComponent {
|
class PrivacyDropdown extends React.PureComponent {
|
||||||
|
|
||||||
constructor (props, context) {
|
constructor (props, context) {
|
||||||
@ -77,7 +72,7 @@ class PrivacyDropdown extends React.PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={this.setRef} className={`privacy-dropdown ${open ? 'active' : ''}`}>
|
<div ref={this.setRef} className={`privacy-dropdown ${open ? 'active' : ''}`}>
|
||||||
<div className='privacy-dropdown__value'><IconButton icon={valueOption.icon} title={intl.formatMessage(messages.change_privacy)} size={18} active={open} inverted onClick={this.handleToggle} style={iconStyle} /></div>
|
<div className='privacy-dropdown__value'><IconButton className='privacy-dropdown__value-icon' icon={valueOption.icon} title={intl.formatMessage(messages.change_privacy)} size={18} active={open} inverted onClick={this.handleToggle} /></div>
|
||||||
<div className='privacy-dropdown__dropdown'>
|
<div className='privacy-dropdown__dropdown'>
|
||||||
{options.map(item =>
|
{options.map(item =>
|
||||||
<div role='button' tabIndex='0' key={item.value} onClick={this.handleClick.bind(this, item.value)} className={`privacy-dropdown__option ${item.value === value ? 'active' : ''}`}>
|
<div role='button' tabIndex='0' key={item.value} onClick={this.handleClick.bind(this, item.value)} className={`privacy-dropdown__option ${item.value === value ? 'active' : ''}`}>
|
||||||
|
@ -40,11 +40,11 @@ class ReplyIndicator extends React.PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='reply-indicator'>
|
<div className='reply-indicator'>
|
||||||
<div style={{ overflow: 'hidden', marginBottom: '5px' }}>
|
<div className='reply-indicator__header'>
|
||||||
<div style={{ float: 'right', lineHeight: '24px' }}><IconButton title={intl.formatMessage(messages.cancel)} icon='times' onClick={this.handleClick} /></div>
|
<div className='reply-indicator__cancel'><IconButton title={intl.formatMessage(messages.cancel)} icon='times' onClick={this.handleClick} /></div>
|
||||||
|
|
||||||
<a href={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' }}>
|
<a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='reply-indicator__display-name'>
|
||||||
<div style={{ float: 'left', marginRight: '5px' }}><Avatar size={24} src={status.getIn(['account', 'avatar'])} staticSrc={status.getIn(['account', 'avatar_static'])} /></div>
|
<div className='reply-indicator__display-avatar'><Avatar size={24} src={status.getIn(['account', 'avatar'])} staticSrc={status.getIn(['account', 'avatar_static'])} /></div>
|
||||||
<DisplayName account={status.get('account')} />
|
<DisplayName account={status.get('account')} />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,11 +6,6 @@ const messages = defineMessages({
|
|||||||
upload: { id: 'upload_button.label', defaultMessage: 'Add media' }
|
upload: { id: 'upload_button.label', defaultMessage: 'Add media' }
|
||||||
});
|
});
|
||||||
|
|
||||||
const iconStyle = {
|
|
||||||
lineHeight: '27px',
|
|
||||||
height: null
|
|
||||||
};
|
|
||||||
|
|
||||||
class UploadButton extends React.PureComponent {
|
class UploadButton extends React.PureComponent {
|
||||||
|
|
||||||
constructor (props, context) {
|
constructor (props, context) {
|
||||||
@ -38,8 +33,8 @@ class UploadButton extends React.PureComponent {
|
|||||||
const { intl, resetFileKey, disabled } = this.props;
|
const { intl, resetFileKey, disabled } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={this.props.style}>
|
<div className='compose-form__upload-button'>
|
||||||
<IconButton icon='camera' title={intl.formatMessage(messages.upload)} disabled={disabled} onClick={this.handleClick} style={iconStyle} size={18} inverted />
|
<IconButton icon='camera' title={intl.formatMessage(messages.upload)} disabled={disabled} onClick={this.handleClick} className='compose-form__upload-button-icon' size={18} inverted />
|
||||||
<input key={resetFileKey} ref={this.setRef} type='file' multiple={false} onChange={this.handleChange} disabled={disabled} style={{ display: 'none' }} />
|
<input key={resetFileKey} ref={this.setRef} type='file' multiple={false} onChange={this.handleChange} disabled={disabled} style={{ display: 'none' }} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -15,10 +15,10 @@ class UploadForm extends React.PureComponent {
|
|||||||
const { intl, media } = this.props;
|
const { intl, media } = this.props;
|
||||||
|
|
||||||
const uploads = media.map(attachment =>
|
const uploads = media.map(attachment =>
|
||||||
<div key={attachment.get('id')} style={{ margin: '5px', flex: '1 1 0' }}>
|
<div className='compose-form__upload' key={attachment.get('id')}>
|
||||||
<Motion defaultStyle={{ scale: 0.8 }} style={{ scale: spring(1, { stiffness: 180, damping: 12 }) }}>
|
<Motion defaultStyle={{ scale: 0.8 }} style={{ scale: spring(1, { stiffness: 180, damping: 12 }) }}>
|
||||||
{({ scale }) =>
|
{({ scale }) =>
|
||||||
<div style={{ transform: `translateZ(0) scale(${scale})`, width: '100%', height: '100px', borderRadius: '4px', background: `url(${attachment.get('preview_url')}) no-repeat center`, backgroundSize: 'cover' }}>
|
<div style={{ transform: `translateZ(0) scale(${scale})`, background: `url(${attachment.get('preview_url')}) no-repeat center` }}>
|
||||||
<IconButton icon='times' title={intl.formatMessage(messages.undo)} size={36} onClick={this.props.onRemoveFile.bind(this, attachment.get('id'))} />
|
<IconButton icon='times' title={intl.formatMessage(messages.undo)} size={36} onClick={this.props.onRemoveFile.bind(this, attachment.get('id'))} />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@ -27,9 +27,9 @@ class UploadForm extends React.PureComponent {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ overflow: 'hidden' }}>
|
<div className='compose-form__upload-wrapper'>
|
||||||
<UploadProgressContainer />
|
<UploadProgressContainer />
|
||||||
<div style={{ display: 'flex', padding: '5px' }}>{uploads}</div>
|
<div className='compose-form__uploads-wrapper'>{uploads}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -13,11 +13,11 @@ class UploadProgress extends React.PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='upload-progress'>
|
<div className='upload-progress'>
|
||||||
<div>
|
<div className='upload-progress__icon'>
|
||||||
<i className='fa fa-upload' />
|
<i className='fa fa-upload' />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ flex: '1 1 auto' }}>
|
<div className='upload-progress__message'>
|
||||||
<FormattedMessage id='upload_progress.label' defaultMessage='Uploading...' />
|
<FormattedMessage id='upload_progress.label' defaultMessage='Uploading...' />
|
||||||
|
|
||||||
<div className='upload-progress__backdrop'>
|
<div className='upload-progress__backdrop'>
|
||||||
|
@ -12,38 +12,23 @@ const messages = defineMessages({
|
|||||||
reject: { id: 'follow_request.reject', defaultMessage: 'Reject' }
|
reject: { id: 'follow_request.reject', defaultMessage: 'Reject' }
|
||||||
});
|
});
|
||||||
|
|
||||||
const outerStyle = {
|
|
||||||
padding: '14px 10px'
|
|
||||||
};
|
|
||||||
|
|
||||||
const panelStyle = {
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'row',
|
|
||||||
padding: '10px 0'
|
|
||||||
};
|
|
||||||
|
|
||||||
const btnStyle = {
|
|
||||||
flex: '1 1 auto',
|
|
||||||
textAlign: 'center'
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccountAuthorize = ({ intl, account, onAuthorize, onReject }) => {
|
const AccountAuthorize = ({ intl, account, onAuthorize, onReject }) => {
|
||||||
const content = { __html: emojify(account.get('note')) };
|
const content = { __html: emojify(account.get('note')) };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className='account-authorize__wrapper'>
|
||||||
<div style={outerStyle}>
|
<div className='account-authorize'>
|
||||||
<Permalink href={account.get('url')} to={`/accounts/${account.get('id')}`} className='detailed-status__display-name' style={{ display: 'block', overflow: 'hidden', marginBottom: '15px' }}>
|
<Permalink href={account.get('url')} to={`/accounts/${account.get('id')}`} className='detailed-status__display-name'>
|
||||||
<div style={{ float: 'left', marginRight: '10px' }}><Avatar src={account.get('avatar')} staticSrc={account.get('avatar_static')} size={48} /></div>
|
<div className='account-authorize__avatar'><Avatar src={account.get('avatar')} staticSrc={account.get('avatar_static')} size={48} /></div>
|
||||||
<DisplayName account={account} />
|
<DisplayName account={account} />
|
||||||
</Permalink>
|
</Permalink>
|
||||||
|
|
||||||
<div style={{ fontSize: '14px' }} className='account__header__content' dangerouslySetInnerHTML={content} />
|
<div className='account__header__content' dangerouslySetInnerHTML={content} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='account--panel' style={panelStyle}>
|
<div className='account--panel'>
|
||||||
<div style={btnStyle}><IconButton title={intl.formatMessage(messages.authorize)} icon='check' onClick={onAuthorize} /></div>
|
<div className='account--panel__button'><IconButton title={intl.formatMessage(messages.authorize)} icon='check' onClick={onAuthorize} /></div>
|
||||||
<div style={btnStyle}><IconButton title={intl.formatMessage(messages.reject)} icon='times' onClick={onReject} /></div>
|
<div className='account--panel__button'><IconButton title={intl.formatMessage(messages.reject)} icon='times' onClick={onReject} /></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -68,7 +68,7 @@ class Followers extends React.PureComponent {
|
|||||||
|
|
||||||
<ScrollContainer scrollKey='followers'>
|
<ScrollContainer scrollKey='followers'>
|
||||||
<div className='scrollable' onScroll={this.handleScroll}>
|
<div className='scrollable' onScroll={this.handleScroll}>
|
||||||
<div>
|
<div className='followers'>
|
||||||
<HeaderContainer accountId={this.props.params.accountId} />
|
<HeaderContainer accountId={this.props.params.accountId} />
|
||||||
{accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} />)}
|
{accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} />)}
|
||||||
<LoadMore onClick={this.handleLoadMore} />
|
<LoadMore onClick={this.handleLoadMore} />
|
||||||
|
@ -68,7 +68,7 @@ class Following extends React.PureComponent {
|
|||||||
|
|
||||||
<ScrollContainer scrollKey='following'>
|
<ScrollContainer scrollKey='following'>
|
||||||
<div className='scrollable' onScroll={this.handleScroll}>
|
<div className='scrollable' onScroll={this.handleScroll}>
|
||||||
<div>
|
<div className='following'>
|
||||||
<HeaderContainer accountId={this.props.params.accountId} />
|
<HeaderContainer accountId={this.props.params.accountId} />
|
||||||
{accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} />)}
|
{accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} />)}
|
||||||
<LoadMore onClick={this.handleLoadMore} />
|
<LoadMore onClick={this.handleLoadMore} />
|
||||||
|
@ -32,7 +32,7 @@ const GettingStarted = ({ intl, me }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Column icon='asterisk' heading={intl.formatMessage(messages.heading)} hideHeadingOnMobile={true}>
|
<Column icon='asterisk' heading={intl.formatMessage(messages.heading)} hideHeadingOnMobile={true}>
|
||||||
<div style={{ position: 'relative' }}>
|
<div className='getting-started__wrapper'>
|
||||||
<ColumnLink icon='users' hideOnMobile={true} text={intl.formatMessage(messages.community_timeline)} to='/timelines/public/local' />
|
<ColumnLink icon='users' hideOnMobile={true} text={intl.formatMessage(messages.community_timeline)} to='/timelines/public/local' />
|
||||||
<ColumnLink icon='globe' hideOnMobile={true} text={intl.formatMessage(messages.public_timeline)} to='/timelines/public' />
|
<ColumnLink icon='globe' hideOnMobile={true} text={intl.formatMessage(messages.public_timeline)} to='/timelines/public' />
|
||||||
<ColumnLink icon='cog' text={intl.formatMessage(messages.preferences)} href='/settings/preferences' />
|
<ColumnLink icon='cog' text={intl.formatMessage(messages.preferences)} href='/settings/preferences' />
|
||||||
|
@ -10,21 +10,6 @@ const messages = defineMessages({
|
|||||||
settings: { id: 'home.settings', defaultMessage: 'Column settings' }
|
settings: { id: 'home.settings', defaultMessage: 'Column settings' }
|
||||||
});
|
});
|
||||||
|
|
||||||
const outerStyle = {
|
|
||||||
padding: '15px'
|
|
||||||
};
|
|
||||||
|
|
||||||
const sectionStyle = {
|
|
||||||
cursor: 'default',
|
|
||||||
display: 'block',
|
|
||||||
fontWeight: '500',
|
|
||||||
marginBottom: '10px'
|
|
||||||
};
|
|
||||||
|
|
||||||
const rowStyle = {
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class ColumnSettings extends React.PureComponent {
|
class ColumnSettings extends React.PureComponent {
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
@ -32,20 +17,20 @@ class ColumnSettings extends React.PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ColumnCollapsable icon='sliders' title={intl.formatMessage(messages.settings)} fullHeight={209} onCollapse={onSave}>
|
<ColumnCollapsable icon='sliders' title={intl.formatMessage(messages.settings)} fullHeight={209} onCollapse={onSave}>
|
||||||
<div className='column-settings--outer' style={outerStyle}>
|
<div className='column-settings__outer'>
|
||||||
<span className='column-settings--section' style={sectionStyle}><FormattedMessage id='home.column_settings.basic' defaultMessage='Basic' /></span>
|
<span className='column-settings__section'><FormattedMessage id='home.column_settings.basic' defaultMessage='Basic' /></span>
|
||||||
|
|
||||||
<div style={rowStyle}>
|
<div className='column-settings__row'>
|
||||||
<SettingToggle settings={settings} settingKey={['shows', 'reblog']} onChange={onChange} label={<FormattedMessage id='home.column_settings.show_reblogs' defaultMessage='Show boosts' />} />
|
<SettingToggle settings={settings} settingKey={['shows', 'reblog']} onChange={onChange} label={<FormattedMessage id='home.column_settings.show_reblogs' defaultMessage='Show boosts' />} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={rowStyle}>
|
<div className='column-settings__row'>
|
||||||
<SettingToggle settings={settings} settingKey={['shows', 'reply']} onChange={onChange} label={<FormattedMessage id='home.column_settings.show_replies' defaultMessage='Show replies' />} />
|
<SettingToggle settings={settings} settingKey={['shows', 'reply']} onChange={onChange} label={<FormattedMessage id='home.column_settings.show_replies' defaultMessage='Show replies' />} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span className='column-settings--section' style={sectionStyle}><FormattedMessage id='home.column_settings.advanced' defaultMessage='Advanced' /></span>
|
<span className='column-settings__section'><FormattedMessage id='home.column_settings.advanced' defaultMessage='Advanced' /></span>
|
||||||
|
|
||||||
<div style={rowStyle}>
|
<div className='column-settings__row'>
|
||||||
<SettingText settings={settings} settingKey={['regex', 'body']} onChange={onChange} label={intl.formatMessage(messages.filter_regex)} />
|
<SettingText settings={settings} settingKey={['regex', 'body']} onChange={onChange} label={intl.formatMessage(messages.filter_regex)} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,15 +1,6 @@
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
|
|
||||||
const style = {
|
|
||||||
display: 'block',
|
|
||||||
fontFamily: 'inherit',
|
|
||||||
marginBottom: '10px',
|
|
||||||
padding: '7px 0',
|
|
||||||
boxSizing: 'border-box',
|
|
||||||
width: '100%'
|
|
||||||
};
|
|
||||||
|
|
||||||
class SettingText extends React.PureComponent {
|
class SettingText extends React.PureComponent {
|
||||||
|
|
||||||
constructor (props, context) {
|
constructor (props, context) {
|
||||||
@ -26,7 +17,6 @@ class SettingText extends React.PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<input
|
<input
|
||||||
style={style}
|
|
||||||
className='setting-text'
|
className='setting-text'
|
||||||
value={settings.getIn(settingKey)}
|
value={settings.getIn(settingKey)}
|
||||||
onChange={this.handleChange}
|
onChange={this.handleChange}
|
||||||
|
@ -51,7 +51,7 @@ class Mutes extends React.PureComponent {
|
|||||||
<Column icon='volume-off' heading={intl.formatMessage(messages.heading)}>
|
<Column icon='volume-off' heading={intl.formatMessage(messages.heading)}>
|
||||||
<ColumnBackButtonSlim />
|
<ColumnBackButtonSlim />
|
||||||
<ScrollContainer scrollKey='mutes'>
|
<ScrollContainer scrollKey='mutes'>
|
||||||
<div className='scrollable' onScroll={this.handleScroll}>
|
<div className='scrollable mutes' onScroll={this.handleScroll}>
|
||||||
{accountIds.map(id =>
|
{accountIds.map(id =>
|
||||||
<AccountContainer key={id} id={id} />
|
<AccountContainer key={id} id={id} />
|
||||||
)}
|
)}
|
||||||
@ -60,6 +60,7 @@ class Mutes extends React.PureComponent {
|
|||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Mutes.propTypes = {
|
Mutes.propTypes = {
|
||||||
|
@ -8,21 +8,6 @@ const messages = defineMessages({
|
|||||||
settings: { id: 'notifications.settings', defaultMessage: 'Column settings' }
|
settings: { id: 'notifications.settings', defaultMessage: 'Column settings' }
|
||||||
});
|
});
|
||||||
|
|
||||||
const outerStyle = {
|
|
||||||
padding: '15px'
|
|
||||||
};
|
|
||||||
|
|
||||||
const sectionStyle = {
|
|
||||||
cursor: 'default',
|
|
||||||
display: 'block',
|
|
||||||
fontWeight: '500',
|
|
||||||
marginBottom: '10px'
|
|
||||||
};
|
|
||||||
|
|
||||||
const rowStyle = {
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class ColumnSettings extends React.PureComponent {
|
class ColumnSettings extends React.PureComponent {
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
@ -34,34 +19,34 @@ class ColumnSettings extends React.PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ColumnCollapsable icon='sliders' title={intl.formatMessage(messages.settings)} fullHeight={616} onCollapse={onSave}>
|
<ColumnCollapsable icon='sliders' title={intl.formatMessage(messages.settings)} fullHeight={616} onCollapse={onSave}>
|
||||||
<div className='column-settings--outer' style={outerStyle}>
|
<div className='column-settings__outer'>
|
||||||
<span className='column-settings--section' style={sectionStyle}><FormattedMessage id='notifications.column_settings.follow' defaultMessage='New followers:' /></span>
|
<span className='column-settings__section'><FormattedMessage id='notifications.column_settings.follow' defaultMessage='New followers:' /></span>
|
||||||
|
|
||||||
<div style={rowStyle}>
|
<div className='column-settings__row'>
|
||||||
<SettingToggle settings={settings} settingKey={['alerts', 'follow']} onChange={onChange} label={alertStr} />
|
<SettingToggle settings={settings} settingKey={['alerts', 'follow']} onChange={onChange} label={alertStr} />
|
||||||
<SettingToggle settings={settings} settingKey={['shows', 'follow']} onChange={onChange} label={showStr} />
|
<SettingToggle settings={settings} settingKey={['shows', 'follow']} onChange={onChange} label={showStr} />
|
||||||
<SettingToggle settings={settings} settingKey={['sounds', 'follow']} onChange={onChange} label={soundStr} />
|
<SettingToggle settings={settings} settingKey={['sounds', 'follow']} onChange={onChange} label={soundStr} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span className='column-settings--section' style={sectionStyle}><FormattedMessage id='notifications.column_settings.favourite' defaultMessage='Favourites:' /></span>
|
<span className='column-settings__section'><FormattedMessage id='notifications.column_settings.favourite' defaultMessage='Favourites:' /></span>
|
||||||
|
|
||||||
<div style={rowStyle}>
|
<div className='column-settings__row'>
|
||||||
<SettingToggle settings={settings} settingKey={['alerts', 'favourite']} onChange={onChange} label={alertStr} />
|
<SettingToggle settings={settings} settingKey={['alerts', 'favourite']} onChange={onChange} label={alertStr} />
|
||||||
<SettingToggle settings={settings} settingKey={['shows', 'favourite']} onChange={onChange} label={showStr} />
|
<SettingToggle settings={settings} settingKey={['shows', 'favourite']} onChange={onChange} label={showStr} />
|
||||||
<SettingToggle settings={settings} settingKey={['sounds', 'favourite']} onChange={onChange} label={soundStr} />
|
<SettingToggle settings={settings} settingKey={['sounds', 'favourite']} onChange={onChange} label={soundStr} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span className='column-settings--section' style={sectionStyle}><FormattedMessage id='notifications.column_settings.mention' defaultMessage='Mentions:' /></span>
|
<span className='column-settings__section'><FormattedMessage id='notifications.column_settings.mention' defaultMessage='Mentions:' /></span>
|
||||||
|
|
||||||
<div style={rowStyle}>
|
<div className='column-settings__row'>
|
||||||
<SettingToggle settings={settings} settingKey={['alerts', 'mention']} onChange={onChange} label={alertStr} />
|
<SettingToggle settings={settings} settingKey={['alerts', 'mention']} onChange={onChange} label={alertStr} />
|
||||||
<SettingToggle settings={settings} settingKey={['shows', 'mention']} onChange={onChange} label={showStr} />
|
<SettingToggle settings={settings} settingKey={['shows', 'mention']} onChange={onChange} label={showStr} />
|
||||||
<SettingToggle settings={settings} settingKey={['sounds', 'mention']} onChange={onChange} label={soundStr} />
|
<SettingToggle settings={settings} settingKey={['sounds', 'mention']} onChange={onChange} label={soundStr} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span className='column-settings--section' style={sectionStyle}><FormattedMessage id='notifications.column_settings.reblog' defaultMessage='Boosts:' /></span>
|
<span className='column-settings__section'><FormattedMessage id='notifications.column_settings.reblog' defaultMessage='Boosts:' /></span>
|
||||||
|
|
||||||
<div style={rowStyle}>
|
<div className='column-settings__row'>
|
||||||
<SettingToggle settings={settings} settingKey={['alerts', 'reblog']} onChange={onChange} label={alertStr} />
|
<SettingToggle settings={settings} settingKey={['alerts', 'reblog']} onChange={onChange} label={alertStr} />
|
||||||
<SettingToggle settings={settings} settingKey={['shows', 'reblog']} onChange={onChange} label={showStr} />
|
<SettingToggle settings={settings} settingKey={['shows', 'reblog']} onChange={onChange} label={showStr} />
|
||||||
<SettingToggle settings={settings} settingKey={['sounds', 'reblog']} onChange={onChange} label={soundStr} />
|
<SettingToggle settings={settings} settingKey={['sounds', 'reblog']} onChange={onChange} label={soundStr} />
|
||||||
|
@ -6,17 +6,13 @@ import Permalink from '../../../components/permalink';
|
|||||||
import emojify from '../../../emoji';
|
import emojify from '../../../emoji';
|
||||||
import escapeTextContentForBrowser from 'escape-html';
|
import escapeTextContentForBrowser from 'escape-html';
|
||||||
|
|
||||||
const linkStyle = {
|
|
||||||
fontWeight: '500'
|
|
||||||
};
|
|
||||||
|
|
||||||
class Notification extends React.PureComponent {
|
class Notification extends React.PureComponent {
|
||||||
|
|
||||||
renderFollow (account, link) {
|
renderFollow (account, link) {
|
||||||
return (
|
return (
|
||||||
<div className='notification notification-follow'>
|
<div className='notification notification-follow'>
|
||||||
<div className='notification__message'>
|
<div className='notification__message'>
|
||||||
<div style={{ position: 'absolute', 'left': '-26px'}}>
|
<div className='notification__favourite-icon-wrapper'>
|
||||||
<i className='fa fa-fw fa-user-plus' />
|
<i className='fa fa-fw fa-user-plus' />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -36,8 +32,8 @@ class Notification extends React.PureComponent {
|
|||||||
return (
|
return (
|
||||||
<div className='notification notification-favourite'>
|
<div className='notification notification-favourite'>
|
||||||
<div className='notification__message'>
|
<div className='notification__message'>
|
||||||
<div style={{ position: 'absolute', 'left': '-26px'}}>
|
<div className='notification__favourite-icon-wrapper'>
|
||||||
<i className='fa fa-fw fa-star' style={{ color: '#ca8f04' }} />
|
<i className='fa fa-fw fa-star star-icon'/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<FormattedMessage id='notification.favourite' defaultMessage='{name} favourited your status' values={{ name: link }} />
|
<FormattedMessage id='notification.favourite' defaultMessage='{name} favourited your status' values={{ name: link }} />
|
||||||
@ -52,7 +48,7 @@ class Notification extends React.PureComponent {
|
|||||||
return (
|
return (
|
||||||
<div className='notification notification-reblog'>
|
<div className='notification notification-reblog'>
|
||||||
<div className='notification__message'>
|
<div className='notification__message'>
|
||||||
<div style={{ position: 'absolute', 'left': '-26px'}}>
|
<div className='notification__favourite-icon-wrapper'>
|
||||||
<i className='fa fa-fw fa-retweet' />
|
<i className='fa fa-fw fa-retweet' />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -69,7 +65,7 @@ class Notification extends React.PureComponent {
|
|||||||
const account = notification.get('account');
|
const account = notification.get('account');
|
||||||
const displayName = account.get('display_name').length > 0 ? account.get('display_name') : account.get('username');
|
const displayName = account.get('display_name').length > 0 ? account.get('display_name') : account.get('username');
|
||||||
const displayNameHTML = { __html: emojify(escapeTextContentForBrowser(displayName)) };
|
const displayNameHTML = { __html: emojify(escapeTextContentForBrowser(displayName)) };
|
||||||
const link = <Permalink className='notification__display-name' style={linkStyle} href={account.get('url')} title={account.get('acct')} to={`/accounts/${account.get('id')}`} dangerouslySetInnerHTML={displayNameHTML} />;
|
const link = <Permalink className='notification__display-name' href={account.get('url')} title={account.get('acct')} to={`/accounts/${account.get('id')}`} dangerouslySetInnerHTML={displayNameHTML} />;
|
||||||
|
|
||||||
switch(notification.get('type')) {
|
switch(notification.get('type')) {
|
||||||
case 'follow':
|
case 'follow':
|
||||||
|
@ -2,23 +2,10 @@ import PropTypes from 'prop-types';
|
|||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import Toggle from 'react-toggle';
|
import Toggle from 'react-toggle';
|
||||||
|
|
||||||
const labelStyle = {
|
|
||||||
display: 'block',
|
|
||||||
lineHeight: '24px',
|
|
||||||
verticalAlign: 'middle'
|
|
||||||
};
|
|
||||||
|
|
||||||
const labelSpanStyle = {
|
|
||||||
display: 'inline-block',
|
|
||||||
verticalAlign: 'middle',
|
|
||||||
marginBottom: '14px',
|
|
||||||
marginLeft: '8px'
|
|
||||||
};
|
|
||||||
|
|
||||||
const SettingToggle = ({ settings, settingKey, label, onChange, htmlFor = '' }) => (
|
const SettingToggle = ({ settings, settingKey, label, onChange, htmlFor = '' }) => (
|
||||||
<label htmlFor={htmlFor} style={labelStyle}>
|
<label htmlFor={htmlFor} className='setting-toggle__label'>
|
||||||
<Toggle checked={settings.getIn(settingKey)} onChange={(e) => onChange(settingKey, e.target.checked)} />
|
<Toggle checked={settings.getIn(settingKey)} onChange={(e) => onChange(settingKey, e.target.checked)} />
|
||||||
<span className='setting-toggle' style={labelSpanStyle}>{label}</span>
|
<span className='setting-toggle'>{label}</span>
|
||||||
</label>
|
</label>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ class Reblogs extends React.PureComponent {
|
|||||||
<ColumnBackButton />
|
<ColumnBackButton />
|
||||||
|
|
||||||
<ScrollContainer scrollKey='reblogs'>
|
<ScrollContainer scrollKey='reblogs'>
|
||||||
<div className='scrollable'>
|
<div className='scrollable reblogs'>
|
||||||
{accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} />)}
|
{accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} />)}
|
||||||
</div>
|
</div>
|
||||||
</ScrollContainer>
|
</ScrollContainer>
|
||||||
|
@ -14,14 +14,13 @@ class StatusCheckBox extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='status-check-box' style={{ display: 'flex' }}>
|
<div className='status-check-box'>
|
||||||
<div
|
<div
|
||||||
className='status__content'
|
className='status__content'
|
||||||
style={{ flex: '1 1 auto', padding: '10px' }}
|
|
||||||
dangerouslySetInnerHTML={content}
|
dangerouslySetInnerHTML={content}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div style={{ flex: '0 0 auto', padding: '10px', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
|
<div className='status-check-box-toggle'>
|
||||||
<Toggle checked={checked} onChange={onToggle} disabled={disabled} />
|
<Toggle checked={checked} onChange={onToggle} disabled={disabled} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -34,10 +34,6 @@ const makeMapStateToProps = () => {
|
|||||||
return mapStateToProps;
|
return mapStateToProps;
|
||||||
};
|
};
|
||||||
|
|
||||||
const textareaStyle = {
|
|
||||||
marginBottom: '10px'
|
|
||||||
};
|
|
||||||
|
|
||||||
class Report extends React.PureComponent {
|
class Report extends React.PureComponent {
|
||||||
|
|
||||||
constructor (props, context) {
|
constructor (props, context) {
|
||||||
@ -86,30 +82,29 @@ class Report extends React.PureComponent {
|
|||||||
<Column heading={intl.formatMessage(messages.heading)} icon='flag'>
|
<Column heading={intl.formatMessage(messages.heading)} icon='flag'>
|
||||||
<ColumnBackButtonSlim />
|
<ColumnBackButtonSlim />
|
||||||
|
|
||||||
<div className='report scrollable' style={{ display: 'flex', flexDirection: 'column', maxHeight: '100%', boxSizing: 'border-box' }}>
|
<div className='report scrollable'>
|
||||||
<div className='report__target' style={{ flex: '0 0 auto', padding: '10px' }}>
|
<div className='report__target'>
|
||||||
<FormattedMessage id='report.target' defaultMessage='Reporting' />
|
<FormattedMessage id='report.target' defaultMessage='Reporting' />
|
||||||
<strong>{account.get('acct')}</strong>
|
<strong>{account.get('acct')}</strong>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ flex: '1 1 auto' }} className='scrollable'>
|
<div className='scrollable report__statuses'>
|
||||||
<div>
|
<div>
|
||||||
{statusIds.map(statusId => <StatusCheckBox id={statusId} key={statusId} disabled={isSubmitting} />)}
|
{statusIds.map(statusId => <StatusCheckBox id={statusId} key={statusId} disabled={isSubmitting} />)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ flex: '0 0 100px', padding: '10px' }}>
|
<div className='report__textarea-wrapper'>
|
||||||
<textarea
|
<textarea
|
||||||
className='report__textarea'
|
className='report__textarea'
|
||||||
placeholder={intl.formatMessage(messages.placeholder)}
|
placeholder={intl.formatMessage(messages.placeholder)}
|
||||||
value={comment}
|
value={comment}
|
||||||
onChange={this.handleCommentChange}
|
onChange={this.handleCommentChange}
|
||||||
style={textareaStyle}
|
|
||||||
disabled={isSubmitting}
|
disabled={isSubmitting}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div style={{ marginTop: '10px', overflow: 'hidden' }}>
|
<div className='report__submit'>
|
||||||
<div style={{ float: 'right' }}><Button disabled={isSubmitting} text={intl.formatMessage(messages.submit)} onClick={this.handleSubmit} /></div>
|
<div className='report__submit-button'><Button disabled={isSubmitting} text={intl.formatMessage(messages.submit)} onClick={this.handleSubmit} /></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -69,10 +69,10 @@ class ActionBar extends React.PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='detailed-status__action-bar'>
|
<div className='detailed-status__action-bar'>
|
||||||
<div style={{ flex: '1 1 auto', textAlign: 'center' }}><IconButton title={intl.formatMessage(messages.reply)} icon={status.get('in_reply_to_id', null) === null ? 'reply' : 'reply-all'} onClick={this.handleReplyClick} /></div>
|
<div className='detailed-status__button'><IconButton title={intl.formatMessage(messages.reply)} icon={status.get('in_reply_to_id', null) === null ? 'reply' : 'reply-all'} onClick={this.handleReplyClick} /></div>
|
||||||
<div style={{ flex: '1 1 auto', textAlign: 'center' }}><IconButton disabled={status.get('visibility') === 'direct' || status.get('visibility') === 'private'} active={status.get('reblogged')} title={intl.formatMessage(messages.reblog)} icon={reblogIcon} onClick={this.handleReblogClick} /></div>
|
<div className='detailed-status__button'><IconButton disabled={status.get('visibility') === 'direct' || status.get('visibility') === 'private'} active={status.get('reblogged')} title={intl.formatMessage(messages.reblog)} icon={reblogIcon} 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>
|
<div className='detailed-status__button'><IconButton animate={true} active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} activeStyle={{ color: '#ca8f04' }} /></div>
|
||||||
<div style={{ flex: '1 1 auto', textAlign: 'center' }}><DropdownMenu size={18} icon='ellipsis-h' items={menu} direction="left" /></div>
|
<div className='detailed-status__button'><DropdownMenu size={18} icon='ellipsis-h' items={menu} direction="left" /></div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,5 @@
|
|||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
|
|
||||||
const contentStyle = {
|
|
||||||
flex: '1 1 auto',
|
|
||||||
padding: '8px',
|
|
||||||
paddingLeft: '14px',
|
|
||||||
overflow: 'hidden'
|
|
||||||
};
|
|
||||||
|
|
||||||
const imageStyle = {
|
|
||||||
display: 'block',
|
|
||||||
width: '100%',
|
|
||||||
height: 'auto',
|
|
||||||
margin: '0',
|
|
||||||
borderRadius: '4px 0 0 4px'
|
|
||||||
};
|
|
||||||
|
|
||||||
const hostStyle = {
|
const hostStyle = {
|
||||||
display: 'block',
|
display: 'block',
|
||||||
marginTop: '5px',
|
marginTop: '5px',
|
||||||
@ -41,7 +26,7 @@ class Card extends React.PureComponent {
|
|||||||
if (card.get('image')) {
|
if (card.get('image')) {
|
||||||
image = (
|
image = (
|
||||||
<div className='status-card__image'>
|
<div className='status-card__image'>
|
||||||
<img src={card.get('image')} alt={card.get('title')} style={imageStyle} />
|
<img src={card.get('image')} alt={card.get('title')} className='status-card__image-image' />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -50,7 +35,7 @@ class Card extends React.PureComponent {
|
|||||||
<a href={card.get('url')} className='status-card' target='_blank' rel='noopener'>
|
<a href={card.get('url')} className='status-card' target='_blank' rel='noopener'>
|
||||||
{image}
|
{image}
|
||||||
|
|
||||||
<div className='status-card__content' style={contentStyle}>
|
<div className='status-card__content'>
|
||||||
<strong className='status-card__title' title={card.get('title')}>{card.get('title')}</strong>
|
<strong className='status-card__title' title={card.get('title')}>{card.get('title')}</strong>
|
||||||
<p className='status-card__description'>{card.get('description').substring(0, 50)}</p>
|
<p className='status-card__description'>{card.get('description').substring(0, 50)}</p>
|
||||||
<span className='status-card__host' style={hostStyle}>{getHostname(card.get('url'))}</span>
|
<span className='status-card__host' style={hostStyle}>{getHostname(card.get('url'))}</span>
|
||||||
|
@ -45,13 +45,13 @@ class DetailedStatus extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (status.get('application')) {
|
if (status.get('application')) {
|
||||||
applicationLink = <span> · <a className='detailed-status__application' style={{ color: 'inherit' }} href={status.getIn(['application', 'website'])} target='_blank' rel='nooopener'>{status.getIn(['application', 'name'])}</a></span>;
|
applicationLink = <span> · <a className='detailed-status__application' href={status.getIn(['application', 'website'])} target='_blank' rel='nooopener'>{status.getIn(['application', 'name'])}</a></span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ padding: '14px 10px' }} className='detailed-status'>
|
<div className='detailed-status'>
|
||||||
<a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='detailed-status__display-name' style={{ display: 'block', overflow: 'hidden', marginBottom: '15px' }}>
|
<a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='detailed-status__display-name'>
|
||||||
<div style={{ float: 'left', marginRight: '10px' }}><Avatar src={status.getIn(['account', 'avatar'])} staticSrc={status.getIn(['account', 'avatar_static'])} size={48} /></div>
|
<div className='.detailed-status__display-avatar'><Avatar src={status.getIn(['account', 'avatar'])} staticSrc={status.getIn(['account', 'avatar_static'])} size={48} /></div>
|
||||||
<DisplayName account={status.get('account')} />
|
<DisplayName account={status.get('account')} />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
@ -60,7 +60,19 @@ class DetailedStatus extends React.PureComponent {
|
|||||||
{media}
|
{media}
|
||||||
|
|
||||||
<div className='detailed-status__meta'>
|
<div className='detailed-status__meta'>
|
||||||
<a className='detailed-status__datetime' style={{ color: 'inherit' }} href={status.get('url')} target='_blank' rel='noopener'><FormattedDate value={new Date(status.get('created_at'))} hour12={false} year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' /></a>{applicationLink} · <Link to={`/statuses/${status.get('id')}/reblogs`} style={{ color: 'inherit', textDecoration: 'none' }}><i className='fa fa-retweet' /><span style={{ fontWeight: '500', fontSize: '12px', marginLeft: '6px', display: 'inline-block' }}><FormattedNumber value={status.get('reblogs_count')} /></span></Link> · <Link to={`/statuses/${status.get('id')}/favourites`} style={{ color: 'inherit', textDecoration: 'none' }}><i className='fa fa-star' /><span style={{ fontWeight: '500', fontSize: '12px', marginLeft: '6px', display: 'inline-block' }}><FormattedNumber value={status.get('favourites_count')} /></span></Link>
|
<a className='detailed-status__datetime' href={status.get('url')} target='_blank' rel='noopener'>
|
||||||
|
<FormattedDate value={new Date(status.get('created_at'))} hour12={false} year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' />
|
||||||
|
</a>{applicationLink} · <Link to={`/statuses/${status.get('id')}/reblogs`} className='detailed-status__link'>
|
||||||
|
<i className='fa fa-retweet' />
|
||||||
|
<span className='detailed-status__reblogs'>
|
||||||
|
<FormattedNumber value={status.get('reblogs_count')} />
|
||||||
|
</span>
|
||||||
|
</Link> · <Link to={`/statuses/${status.get('id')}/favourites`} className='detailed-status__link'>
|
||||||
|
<i className='fa fa-star' />
|
||||||
|
<span className='detailed-status__favorites'>
|
||||||
|
<FormattedNumber value={status.get('favourites_count')} />
|
||||||
|
</span>
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -151,7 +151,7 @@ class Status extends React.PureComponent {
|
|||||||
<ColumnBackButton />
|
<ColumnBackButton />
|
||||||
|
|
||||||
<ScrollContainer scrollKey='thread'>
|
<ScrollContainer scrollKey='thread'>
|
||||||
<div className='scrollable'>
|
<div className='scrollable detailed-status__wrapper'>
|
||||||
{ancestors}
|
{ancestors}
|
||||||
|
|
||||||
<DetailedStatus status={status} autoPlayGif={autoPlayGif} me={me} onOpenVideo={this.handleOpenVideo} onOpenMedia={this.handleOpenMedia} />
|
<DetailedStatus status={status} autoPlayGif={autoPlayGif} me={me} onOpenVideo={this.handleOpenVideo} onOpenMedia={this.handleOpenMedia} />
|
||||||
|
@ -40,13 +40,13 @@ class BoostModal extends React.PureComponent {
|
|||||||
<div className='modal-root__modal boost-modal'>
|
<div className='modal-root__modal boost-modal'>
|
||||||
<div className='boost-modal__container'>
|
<div className='boost-modal__container'>
|
||||||
<div className='status light'>
|
<div className='status light'>
|
||||||
<div style={{ fontSize: '15px' }}>
|
<div className='boost-modal__status-header'>
|
||||||
<div style={{ float: 'right', fontSize: '14px' }}>
|
<div className='boost-modal__status-time'>
|
||||||
<a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener'><RelativeTimestamp timestamp={status.get('created_at')} /></a>
|
<a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener'><RelativeTimestamp timestamp={status.get('created_at')} /></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a onClick={this.handleAccountClick} href={status.getIn(['account', 'url'])} className='status__display-name' style={{ display: 'block', maxWidth: '100%', paddingRight: '25px' }}>
|
<a onClick={this.handleAccountClick} href={status.getIn(['account', 'url'])} className='status__display-name'>
|
||||||
<div className='status__avatar' style={{ position: 'absolute', left: '10px', top: '10px', width: '48px', height: '48px' }}>
|
<div className='status__avatar'>
|
||||||
<Avatar src={status.getIn(['account', 'avatar'])} staticSrc={status.getIn(['account', 'avatar_static'])} size={48} />
|
<Avatar src={status.getIn(['account', 'avatar'])} staticSrc={status.getIn(['account', 'avatar_static'])} size={48} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ class ColumnHeader extends React.PureComponent {
|
|||||||
let icon = '';
|
let icon = '';
|
||||||
|
|
||||||
if (this.props.icon) {
|
if (this.props.icon) {
|
||||||
icon = <i className={`fa fa-fw fa-${this.props.icon}`} style={{ display: 'inline-block', marginRight: '5px' }} />;
|
icon = <i className={`fa fa-fw fa-${this.props.icon} column-header__icon`} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,29 +1,18 @@
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Link } from 'react-router';
|
import { Link } from 'react-router';
|
||||||
|
|
||||||
const outerStyle = {
|
|
||||||
padding: '15px',
|
|
||||||
fontSize: '16px',
|
|
||||||
textDecoration: 'none'
|
|
||||||
};
|
|
||||||
|
|
||||||
const iconStyle = {
|
|
||||||
display: 'inline-block',
|
|
||||||
marginRight: '5px'
|
|
||||||
};
|
|
||||||
|
|
||||||
const ColumnLink = ({ icon, text, to, href, method, hideOnMobile }) => {
|
const ColumnLink = ({ icon, text, to, href, method, hideOnMobile }) => {
|
||||||
if (href) {
|
if (href) {
|
||||||
return (
|
return (
|
||||||
<a href={href} style={outerStyle} className={`column-link ${hideOnMobile ? 'hidden-on-mobile' : ''}`} data-method={method}>
|
<a href={href} style={outerStyle} className={`column-link ${hideOnMobile ? 'hidden-on-mobile' : ''}`} data-method={method}>
|
||||||
<i className={`fa fa-fw fa-${icon}`} style={iconStyle} />
|
<i className={`fa fa-fw fa-${icon} column-link__icon`} />
|
||||||
{text}
|
{text}
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<Link to={to} style={outerStyle} className={`column-link ${hideOnMobile ? 'hidden-on-mobile' : ''}`}>
|
<Link to={to} className={`column-link ${hideOnMobile ? 'hidden-on-mobile' : ''}`}>
|
||||||
<i className={`fa fa-fw fa-${icon}`} style={iconStyle} />
|
<i className={`fa fa-fw fa-${icon} column-link__icon`} />
|
||||||
{text}
|
{text}
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
|
@ -1,16 +1,10 @@
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
const style = {
|
|
||||||
display: 'flex',
|
|
||||||
flex: '1 1 auto',
|
|
||||||
overflowX: 'auto'
|
|
||||||
};
|
|
||||||
|
|
||||||
class ColumnsArea extends React.PureComponent {
|
class ColumnsArea extends React.PureComponent {
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div className='columns-area' style={style}>
|
<div className='columns-area'>
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -10,40 +10,6 @@ const messages = defineMessages({
|
|||||||
close: { id: 'lightbox.close', defaultMessage: 'Close' }
|
close: { id: 'lightbox.close', defaultMessage: 'Close' }
|
||||||
});
|
});
|
||||||
|
|
||||||
const leftNavStyle = {
|
|
||||||
position: 'absolute',
|
|
||||||
background: 'rgba(0, 0, 0, 0.5)',
|
|
||||||
padding: '30px 15px',
|
|
||||||
cursor: 'pointer',
|
|
||||||
fontSize: '24px',
|
|
||||||
top: '0',
|
|
||||||
left: '-61px',
|
|
||||||
boxSizing: 'border-box',
|
|
||||||
height: '100%',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center'
|
|
||||||
};
|
|
||||||
|
|
||||||
const rightNavStyle = {
|
|
||||||
position: 'absolute',
|
|
||||||
background: 'rgba(0, 0, 0, 0.5)',
|
|
||||||
padding: '30px 15px',
|
|
||||||
cursor: 'pointer',
|
|
||||||
fontSize: '24px',
|
|
||||||
top: '0',
|
|
||||||
right: '-61px',
|
|
||||||
boxSizing: 'border-box',
|
|
||||||
height: '100%',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center'
|
|
||||||
};
|
|
||||||
|
|
||||||
const closeStyle = {
|
|
||||||
position: 'absolute',
|
|
||||||
top: '4px',
|
|
||||||
right: '4px'
|
|
||||||
};
|
|
||||||
|
|
||||||
class MediaModal extends React.PureComponent {
|
class MediaModal extends React.PureComponent {
|
||||||
|
|
||||||
constructor (props, context) {
|
constructor (props, context) {
|
||||||
@ -99,8 +65,8 @@ class MediaModal extends React.PureComponent {
|
|||||||
leftNav = rightNav = content = '';
|
leftNav = rightNav = content = '';
|
||||||
|
|
||||||
if (media.size > 1) {
|
if (media.size > 1) {
|
||||||
leftNav = <div role='button' tabIndex='0' style={leftNavStyle} className='modal-container__nav' onClick={this.handlePrevClick}><i className='fa fa-fw fa-chevron-left' /></div>;
|
leftNav = <div role='button' tabIndex='0' className='modal-container__nav modal-container__nav--left' onClick={this.handlePrevClick}><i className='fa fa-fw fa-chevron-left' /></div>;
|
||||||
rightNav = <div role='button' tabIndex='0' style={rightNavStyle} className='modal-container__nav' onClick={this.handleNextClick}><i className='fa fa-fw fa-chevron-right' /></div>;
|
rightNav = <div role='button' tabIndex='0' className='modal-container__nav modal-container__nav--right' onClick={this.handleNextClick}><i className='fa fa-fw fa-chevron-right' /></div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attachment.get('type') === 'image') {
|
if (attachment.get('type') === 'image') {
|
||||||
@ -113,8 +79,8 @@ class MediaModal extends React.PureComponent {
|
|||||||
<div className='modal-root__modal media-modal'>
|
<div className='modal-root__modal media-modal'>
|
||||||
{leftNav}
|
{leftNav}
|
||||||
|
|
||||||
<div>
|
<div className='media-modal__content'>
|
||||||
<IconButton title={intl.formatMessage(messages.close)} icon='times' onClick={onClose} size={16} style={closeStyle} />
|
<IconButton className='media-modal__close' title={intl.formatMessage(messages.close)} icon='times' onClick={onClose} size={16} />
|
||||||
{content}
|
{content}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ class ModalRoot extends React.PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={key}>
|
<div key={key}>
|
||||||
<div role='presentation' className='modal-root__overlay' style={{ opacity: style.opacity, transform: `translateZ(0px)` }} onClick={onClose} />
|
<div role='presentation' className='modal-root__overlay' style={{ opacity: style.opacity }} onClick={onClose} />
|
||||||
<div className='modal-root__container' style={{ opacity: style.opacity, transform: `translateZ(0px) scale(${style.scale})` }}>
|
<div className='modal-root__container' style={{ opacity: style.opacity, transform: `translateZ(0px) scale(${style.scale})` }}>
|
||||||
<SpecificComponent {...props} onClose={onClose} />
|
<SpecificComponent {...props} onClose={onClose} />
|
||||||
</div>
|
</div>
|
||||||
|
@ -9,13 +9,6 @@ const messages = defineMessages({
|
|||||||
close: { id: 'lightbox.close', defaultMessage: 'Close' }
|
close: { id: 'lightbox.close', defaultMessage: 'Close' }
|
||||||
});
|
});
|
||||||
|
|
||||||
const closeStyle = {
|
|
||||||
position: 'absolute',
|
|
||||||
zIndex: '100',
|
|
||||||
top: '4px',
|
|
||||||
right: '4px'
|
|
||||||
};
|
|
||||||
|
|
||||||
class VideoModal extends React.PureComponent {
|
class VideoModal extends React.PureComponent {
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
@ -26,7 +19,7 @@ class VideoModal extends React.PureComponent {
|
|||||||
return (
|
return (
|
||||||
<div className='modal-root__modal media-modal'>
|
<div className='modal-root__modal media-modal'>
|
||||||
<div>
|
<div>
|
||||||
<div style={closeStyle}><IconButton title={intl.formatMessage(messages.close)} icon='times' overlay onClick={onClose} /></div>
|
<div className='media-modal__close'><IconButton title={intl.formatMessage(messages.close)} icon='times' overlay onClick={onClose} /></div>
|
||||||
<ExtendedVideoPlayer src={url} muted={false} controls={true} time={time} />
|
<ExtendedVideoPlayer src={url} muted={false} controls={true} time={time} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user