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:
@ -14,11 +14,6 @@ const messages = defineMessages({
|
||||
unmute: { id: 'account.unmute', defaultMessage: 'Unmute' }
|
||||
});
|
||||
|
||||
const buttonsStyle = {
|
||||
padding: '10px',
|
||||
height: '18px'
|
||||
};
|
||||
|
||||
class Account extends React.PureComponent {
|
||||
|
||||
constructor (props, context) {
|
||||
@ -68,13 +63,13 @@ class Account extends React.PureComponent {
|
||||
|
||||
return (
|
||||
<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')}`}>
|
||||
<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} />
|
||||
</Permalink>
|
||||
|
||||
<div style={buttonsStyle}>
|
||||
<div className='account__relationship'>
|
||||
{buttons}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -150,8 +150,7 @@ class AutosuggestTextarea extends React.Component {
|
||||
render () {
|
||||
const { value, suggestions, disabled, placeholder, onKeyUp } = this.props;
|
||||
const { suggestionsHidden, selectedSuggestion } = this.state;
|
||||
const className = 'autosuggest-textarea__textarea';
|
||||
const style = { direction: 'ltr' };
|
||||
const style = { direction: 'ltr' };
|
||||
|
||||
if (isRtl(value)) {
|
||||
style.direction = 'rtl';
|
||||
@ -161,7 +160,7 @@ class AutosuggestTextarea extends React.Component {
|
||||
<div className='autosuggest-textarea'>
|
||||
<textarea
|
||||
ref={this.setTextarea}
|
||||
className={className}
|
||||
className='autosuggest-textarea__textarea'
|
||||
disabled={disabled}
|
||||
placeholder={placeholder}
|
||||
autoFocus={true}
|
||||
|
@ -38,7 +38,7 @@ class Avatar extends React.PureComponent {
|
||||
|
||||
return (
|
||||
<div
|
||||
className='avatar'
|
||||
className='account__avatar'
|
||||
onMouseEnter={this.handleMouseEnter}
|
||||
onMouseLeave={this.handleMouseLeave}
|
||||
style={style}
|
||||
|
@ -15,25 +15,11 @@ class Button extends React.PureComponent {
|
||||
|
||||
render () {
|
||||
const style = {
|
||||
fontFamily: 'inherit',
|
||||
display: this.props.block ? 'block' : 'inline-block',
|
||||
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`,
|
||||
height: `${this.props.size}px`,
|
||||
cursor: 'pointer',
|
||||
lineHeight: `${this.props.size}px`,
|
||||
borderRadius: '4px',
|
||||
textDecoration: 'none',
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
overflow: 'hidden'
|
||||
lineHeight: `${this.props.size}px`
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -1,11 +1,6 @@
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const iconStyle = {
|
||||
display: 'inline-block',
|
||||
marginRight: '5px'
|
||||
};
|
||||
|
||||
class ColumnBackButton extends React.PureComponent {
|
||||
|
||||
constructor (props, context) {
|
||||
@ -21,7 +16,7 @@ class ColumnBackButton extends React.PureComponent {
|
||||
render () {
|
||||
return (
|
||||
<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' />
|
||||
</div>
|
||||
);
|
||||
|
@ -1,21 +1,6 @@
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
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 {
|
||||
|
||||
constructor (props, context) {
|
||||
@ -29,15 +14,14 @@ class ColumnBackButtonSlim extends React.PureComponent {
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div style={{ position: 'relative' }}>
|
||||
<div role='button' tabIndex='0' style={outerStyle} onClick={this.handleClick} className='column-back-button'>
|
||||
<i className='fa fa-fw fa-chevron-left' style={iconStyle} />
|
||||
<div className='column-back-button--slim'>
|
||||
<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 column-back-button__icon' />
|
||||
<FormattedMessage id='column_back_button.label' defaultMessage='Back' />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ColumnBackButtonSlim.contextTypes = {
|
||||
|
@ -1,16 +1,6 @@
|
||||
import { Motion, spring } from 'react-motion';
|
||||
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 {
|
||||
|
||||
constructor (props, context) {
|
||||
@ -38,8 +28,8 @@ class ColumnCollapsable extends React.PureComponent {
|
||||
const collapsedClassName = collapsed ? 'collapsable-collapsed' : 'collapsable';
|
||||
|
||||
return (
|
||||
<div style={{ position: 'relative' }}>
|
||||
<div role='button' tabIndex='0' title={`${title}`} style={{...iconStyle }} className={`column-icon ${collapsedClassName}`} onClick={this.handleToggleCollapsed}>
|
||||
<div className='column-collapsable'>
|
||||
<div role='button' tabIndex='0' title={`${title}`} className={`column-icon ${collapsedClassName}`} onClick={this.handleToggleCollapsed}>
|
||||
<i className={`fa fa-${icon}`} />
|
||||
</div>
|
||||
|
||||
|
@ -9,8 +9,8 @@ class DisplayName extends React.PureComponent {
|
||||
const displayNameHTML = { __html: emojify(escapeTextContentForBrowser(displayName)) };
|
||||
|
||||
return (
|
||||
<span style={{ display: 'block', maxWidth: '100%', overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis' }} className='display-name'>
|
||||
<strong style={{ fontWeight: '500' }} dangerouslySetInnerHTML={displayNameHTML} /> <span style={{ fontSize: '14px' }}>@{this.props.account.get('acct')}</span>
|
||||
<span className='display-name'>
|
||||
<strong className='display-name__html' dangerouslySetInnerHTML={displayNameHTML} /> <span className='display-name__account'>@{this.props.account.get('acct')}</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
@ -28,14 +28,14 @@ class DropdownMenu extends React.PureComponent {
|
||||
|
||||
renderItem (item, i) {
|
||||
if (item === null) {
|
||||
return <li key={i} className='dropdown__sep' />;
|
||||
return <li key={ 'sep' + i } className='dropdown__sep' />;
|
||||
}
|
||||
|
||||
const { text, action, href = '#' } = item;
|
||||
|
||||
return (
|
||||
<li key={i}>
|
||||
<a href={href} target='_blank' rel='noopener' onClick={this.handleClick.bind(this, i)}>
|
||||
<li className='dropdown__content-list-item' key={ text + i }>
|
||||
<a href={href} target='_blank' rel='noopener' onClick={this.handleClick.bind(this, i)} className='dropdown__content-list-link'>
|
||||
{text}
|
||||
</a>
|
||||
</li>
|
||||
@ -49,11 +49,11 @@ class DropdownMenu extends React.PureComponent {
|
||||
return (
|
||||
<Dropdown ref={this.setRef}>
|
||||
<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>
|
||||
|
||||
<DropdownContent className={directionClass} style={{ lineHeight: '18px', textAlign: 'left' }}>
|
||||
<ul>
|
||||
<DropdownContent className={directionClass}>
|
||||
<ul className='dropdown__content-list'>
|
||||
{items.map(this.renderItem)}
|
||||
</ul>
|
||||
</DropdownContent>
|
||||
|
@ -47,6 +47,10 @@ class IconButton extends React.PureComponent {
|
||||
classes.push('overlayed');
|
||||
}
|
||||
|
||||
if (this.props.className) {
|
||||
classes.push(this.props.className)
|
||||
}
|
||||
|
||||
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 }}>
|
||||
{({ rotate }) =>
|
||||
@ -66,6 +70,7 @@ class IconButton extends React.PureComponent {
|
||||
}
|
||||
|
||||
IconButton.propTypes = {
|
||||
className: PropTypes.string,
|
||||
title: PropTypes.string.isRequired,
|
||||
icon: PropTypes.string.isRequired,
|
||||
onClick: PropTypes.func,
|
||||
|
@ -1,14 +1,7 @@
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
const style = {
|
||||
textAlign: 'center',
|
||||
fontSize: '16px',
|
||||
fontWeight: '500',
|
||||
paddingTop: '120px'
|
||||
};
|
||||
|
||||
const LoadingIndicator = () => (
|
||||
<div className='loading-indicator' style={style}>
|
||||
<div className='loading-indicator'>
|
||||
<FormattedMessage id='loading_indicator.label' defaultMessage='Loading...' />
|
||||
</div>
|
||||
);
|
||||
|
@ -8,72 +8,7 @@ const messages = defineMessages({
|
||||
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 {
|
||||
|
||||
constructor (props, context) {
|
||||
super(props, context);
|
||||
this.handleClick = this.handleClick.bind(this);
|
||||
@ -147,24 +82,26 @@ class Item extends React.PureComponent {
|
||||
if (attachment.get('type') === 'image') {
|
||||
thumbnail = (
|
||||
<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}
|
||||
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') {
|
||||
const autoPlay = !isIOS() && this.props.autoPlayGif;
|
||||
|
||||
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
|
||||
className='media-gallery__item-gifv-thumbnail'
|
||||
role='application'
|
||||
src={attachment.get('url')}
|
||||
onClick={this.handleClick}
|
||||
autoPlay={autoPlay}
|
||||
loop={true}
|
||||
muted={true}
|
||||
style={gifvThumbStyle}
|
||||
/>
|
||||
|
||||
<span className='media-gallery__gifv__label'>GIF</span>
|
||||
@ -173,7 +110,7 @@ class Item extends React.PureComponent {
|
||||
}
|
||||
|
||||
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}
|
||||
</div>
|
||||
);
|
||||
@ -223,9 +160,9 @@ class MediaGallery extends React.PureComponent {
|
||||
}
|
||||
|
||||
children = (
|
||||
<div role='button' tabIndex='0' style={spoilerStyle} className='media-spoiler' onClick={this.handleOpen}>
|
||||
<span style={spoilerSpanStyle}>{warning}</span>
|
||||
<span style={spoilerSubSpanStyle}><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span>
|
||||
<div role='button' tabIndex='0' className='media-spoiler' onClick={this.handleOpen}>
|
||||
<span className='media-spoiler__warning'>{warning}</span>
|
||||
<span className='media-spoiler__trigger'><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
@ -234,8 +171,8 @@ class MediaGallery extends React.PureComponent {
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ ...outerStyle, height: `${this.props.height}px` }}>
|
||||
<div style={{ ...spoilerButtonStyle, display: !this.state.visible ? 'none' : 'block' }}>
|
||||
<div className='media-gallery' style={{ height: `${this.props.height}px` }}>
|
||||
<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} />
|
||||
</div>
|
||||
|
||||
|
@ -15,9 +15,9 @@ class Permalink extends React.Component {
|
||||
}
|
||||
|
||||
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 = {
|
||||
className: PropTypes.string,
|
||||
href: PropTypes.string.isRequired,
|
||||
to: PropTypes.string.isRequired,
|
||||
children: PropTypes.node
|
||||
|
@ -50,9 +50,9 @@ class Status extends React.PureComponent {
|
||||
const displayNameHTML = { __html: emojify(escapeTextContentForBrowser(displayName)) };
|
||||
|
||||
return (
|
||||
<div style={{ cursor: 'default' }}>
|
||||
<div className='status__wrapper'>
|
||||
<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> }} />
|
||||
</div>
|
||||
|
||||
@ -73,13 +73,13 @@ class Status extends React.PureComponent {
|
||||
|
||||
return (
|
||||
<div className={this.props.muted ? 'status muted' : 'status'}>
|
||||
<div style={{ fontSize: '15px' }}>
|
||||
<div style={{ float: 'right', fontSize: '14px' }}>
|
||||
<div className='status__info'>
|
||||
<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>
|
||||
</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' }}>
|
||||
<div className='status__avatar' style={{ position: 'absolute', left: '10px', top: '10px', width: '48px', height: '48px' }}>
|
||||
<a onClick={this.handleAccountClick.bind(this, status.getIn(['account', 'id']))} href={status.getIn(['account', 'url'])} className='status__display-name'>
|
||||
<div className='status__avatar'>
|
||||
<Avatar src={status.getIn(['account', 'avatar'])} staticSrc={status.getIn(['account', 'avatar_static'])} size={48} />
|
||||
</div>
|
||||
|
||||
|
@ -100,12 +100,12 @@ class StatusActionBar extends React.PureComponent {
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ marginTop: '10px', overflow: 'hidden' }}>
|
||||
<div style={{ float: 'left', marginRight: '18px'}}><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 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'>
|
||||
<div className='status__action-bar-button-wrapper'><IconButton title={reply_title} icon={reply_icon} onClick={this.handleReplyClick} /></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 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" />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -112,7 +112,7 @@ class StatusContent extends React.PureComponent {
|
||||
}
|
||||
|
||||
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' : '' }} >
|
||||
<span dangerouslySetInnerHTML={spoilerContent} /> <a tabIndex='0' className='status__content__spoiler-link' role='button' onClick={this.handleSpoilerClick}>{toggleText}</a>
|
||||
</p>
|
||||
@ -126,7 +126,7 @@ class StatusContent extends React.PureComponent {
|
||||
return (
|
||||
<div
|
||||
className='status__content'
|
||||
style={{ cursor: 'pointer', ...directionStyle }}
|
||||
style={{ ...directionStyle }}
|
||||
onMouseDown={this.handleMouseDown}
|
||||
onMouseUp={this.handleMouseUp}
|
||||
dangerouslySetInnerHTML={content}
|
||||
@ -135,7 +135,7 @@ class StatusContent extends React.PureComponent {
|
||||
} else {
|
||||
return (
|
||||
<div
|
||||
className='status__content'
|
||||
className='status__content status__content--no-action'
|
||||
style={{ ...directionStyle }}
|
||||
dangerouslySetInnerHTML={content}
|
||||
/>
|
||||
|
@ -79,7 +79,7 @@ class StatusList extends React.PureComponent {
|
||||
<div className='scrollable' ref={this.setRef}>
|
||||
{unread}
|
||||
|
||||
<div>
|
||||
<div className='status-list'>
|
||||
{prepend}
|
||||
|
||||
{statusIds.map((statusId) => {
|
||||
|
@ -11,67 +11,6 @@ const messages = defineMessages({
|
||||
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 {
|
||||
|
||||
constructor (props, context) {
|
||||
@ -83,6 +22,7 @@ class VideoPlayer extends React.PureComponent {
|
||||
hasAudio: true,
|
||||
videoError: false
|
||||
};
|
||||
|
||||
this.handleClick = this.handleClick.bind(this);
|
||||
this.handleVideoClick = this.handleVideoClick.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;
|
||||
|
||||
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} />
|
||||
</div>
|
||||
);
|
||||
|
||||
let expandButton = (
|
||||
<div style={expandButtonStyle} >
|
||||
<div className='status__video-player-expand'>
|
||||
<IconButton overlay title={intl.formatMessage(messages.expand_video)} icon='expand' onClick={this.handleExpand} />
|
||||
</div>
|
||||
);
|
||||
@ -185,7 +125,7 @@ class VideoPlayer extends React.PureComponent {
|
||||
|
||||
if (this.state.hasAudio) {
|
||||
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} />
|
||||
</div>
|
||||
);
|
||||
@ -194,18 +134,18 @@ class VideoPlayer extends React.PureComponent {
|
||||
if (!this.state.visible) {
|
||||
if (sensitive) {
|
||||
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}
|
||||
<span style={spoilerSpanStyle}><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__warning'><FormattedMessage id='status.sensitive_warning' defaultMessage='Sensitive content' /></span>
|
||||
<span className='media-spoiler__trigger'><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
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}
|
||||
<span style={spoilerSpanStyle}><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__warning'><FormattedMessage id='status.media_hidden' defaultMessage='Media hidden' /></span>
|
||||
<span className='media-spoiler__trigger'><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -213,27 +153,27 @@ class VideoPlayer extends React.PureComponent {
|
||||
|
||||
if (this.state.preview && !autoplay) {
|
||||
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}
|
||||
<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>
|
||||
);
|
||||
}
|
||||
|
||||
if (this.state.videoError) {
|
||||
return (
|
||||
<div style={{...coverStyle, 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>
|
||||
<div style={{ width: `${width}px`, height: `${height}px` }} className='video-error-cover' >
|
||||
<span className='media-spoiler__warning'><FormattedMessage id='video_player.video_error' defaultMessage='Video could not be played' /></span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
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}
|
||||
{muteButton}
|
||||
{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>
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user