Merge branch 'accessibility' into 'develop'
Accessibility improvements See merge request soapbox-pub/soapbox-fe!697
This commit is contained in:
commit
e652de227c
|
@ -9,8 +9,9 @@ export function openModal(type, props) {
|
|||
};
|
||||
}
|
||||
|
||||
export function closeModal() {
|
||||
export function closeModal(type) {
|
||||
return {
|
||||
type: MODAL_CLOSE,
|
||||
modalType: type,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ export default class Button extends React.PureComponent {
|
|||
|
||||
if (this.props.to) {
|
||||
return (
|
||||
<Link to={this.props.to}>
|
||||
<Link to={this.props.to} tabIndex={-1}>
|
||||
{btn}
|
||||
</Link>
|
||||
);
|
||||
|
|
|
@ -45,7 +45,9 @@ class DropdownMenu extends React.PureComponent {
|
|||
document.addEventListener('click', this.handleDocumentClick, false);
|
||||
document.addEventListener('keydown', this.handleKeyDown, false);
|
||||
document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
|
||||
if (this.focusedItem && this.props.openedViaKeyboard) this.focusedItem.focus();
|
||||
if (this.focusedItem && this.props.openedViaKeyboard) {
|
||||
this.focusedItem.focus({ preventScroll: true });
|
||||
}
|
||||
this.setState({ mounted: true });
|
||||
}
|
||||
|
||||
|
@ -66,38 +68,42 @@ class DropdownMenu extends React.PureComponent {
|
|||
handleKeyDown = e => {
|
||||
const items = Array.from(this.node.getElementsByTagName('a'));
|
||||
const index = items.indexOf(document.activeElement);
|
||||
let element;
|
||||
let element = null;
|
||||
|
||||
switch(e.key) {
|
||||
case 'ArrowDown':
|
||||
element = items[index+1];
|
||||
if (element) {
|
||||
element.focus();
|
||||
}
|
||||
element = items[index+1] || items[0];
|
||||
break;
|
||||
case 'ArrowUp':
|
||||
element = items[index-1];
|
||||
if (element) {
|
||||
element.focus();
|
||||
element = items[index-1] || items[items.length-1];
|
||||
break;
|
||||
case 'Tab':
|
||||
if (e.shiftKey) {
|
||||
element = items[index-1] || items[items.length-1];
|
||||
} else {
|
||||
element = items[index+1] || items[0];
|
||||
}
|
||||
break;
|
||||
case 'Home':
|
||||
element = items[0];
|
||||
if (element) {
|
||||
element.focus();
|
||||
}
|
||||
break;
|
||||
case 'End':
|
||||
element = items[items.length-1];
|
||||
if (element) {
|
||||
element.focus();
|
||||
}
|
||||
break;
|
||||
case 'Escape':
|
||||
this.props.onClose();
|
||||
break;
|
||||
}
|
||||
|
||||
if (element) {
|
||||
element.focus();
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
handleItemKeyDown = e => {
|
||||
if (e.key === 'Enter') {
|
||||
handleItemKeyPress = e => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
this.handleClick(e);
|
||||
}
|
||||
}
|
||||
|
@ -151,7 +157,7 @@ class DropdownMenu extends React.PureComponent {
|
|||
ref={i === 0 ? this.setFocusRef : null}
|
||||
onClick={this.handleClick}
|
||||
onAuxClick={this.handleAuxClick}
|
||||
onKeyDown={this.handleItemKeyDown}
|
||||
onKeyPress={this.handleItemKeyPress}
|
||||
data-index={i}
|
||||
target={newTab ? '_blank' : null}
|
||||
data-method={isLogout ? 'delete' : null}
|
||||
|
@ -226,19 +232,36 @@ export default class Dropdown extends React.PureComponent {
|
|||
}
|
||||
|
||||
handleClose = () => {
|
||||
if (this.activeElement) {
|
||||
this.activeElement.focus();
|
||||
this.activeElement = null;
|
||||
}
|
||||
this.props.onClose(this.state.id);
|
||||
}
|
||||
|
||||
handleKeyDown = e => {
|
||||
handleMouseDown = () => {
|
||||
if (!this.state.open) {
|
||||
this.activeElement = document.activeElement;
|
||||
}
|
||||
}
|
||||
|
||||
handleButtonKeyDown = (e) => {
|
||||
switch(e.key) {
|
||||
case ' ':
|
||||
case 'Enter':
|
||||
this.handleMouseDown();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
handleKeyPress = (e) => {
|
||||
switch(e.key) {
|
||||
case ' ':
|
||||
case 'Enter':
|
||||
this.handleClick(e);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
break;
|
||||
case 'Escape':
|
||||
this.handleClose();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -276,7 +299,7 @@ export default class Dropdown extends React.PureComponent {
|
|||
const open = this.state.id === openDropdownId;
|
||||
|
||||
return (
|
||||
<div onKeyDown={this.handleKeyDown}>
|
||||
<div>
|
||||
<IconButton
|
||||
icon={icon}
|
||||
title={title}
|
||||
|
@ -285,6 +308,9 @@ export default class Dropdown extends React.PureComponent {
|
|||
size={size}
|
||||
ref={this.setTargetRef}
|
||||
onClick={this.handleClick}
|
||||
onMouseDown={this.handleMouseDown}
|
||||
onKeyDown={this.handleButtonKeyDown}
|
||||
onKeyPress={this.handleKeyPress}
|
||||
/>
|
||||
|
||||
<Overlay show={open} placement={dropdownPlacement} target={this.findTarget}>
|
||||
|
|
|
@ -13,8 +13,10 @@ export default class IconButton extends React.PureComponent {
|
|||
title: PropTypes.string.isRequired,
|
||||
icon: PropTypes.string.isRequired,
|
||||
onClick: PropTypes.func,
|
||||
onMouseDown: PropTypes.func,
|
||||
onKeyUp: PropTypes.func,
|
||||
onKeyDown: PropTypes.func,
|
||||
onKeyPress: PropTypes.func,
|
||||
onMouseEnter: PropTypes.func,
|
||||
onMouseLeave: PropTypes.func,
|
||||
size: PropTypes.number,
|
||||
|
@ -54,6 +56,30 @@ export default class IconButton extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
handleMouseDown = (e) => {
|
||||
if (!this.props.disabled && this.props.onMouseDown) {
|
||||
this.props.onMouseDown(e);
|
||||
}
|
||||
}
|
||||
|
||||
handleKeyDown = (e) => {
|
||||
if (!this.props.disabled && this.props.onKeyDown) {
|
||||
this.props.onKeyDown(e);
|
||||
}
|
||||
}
|
||||
|
||||
handleKeyUp = (e) => {
|
||||
if (!this.props.disabled && this.props.onKeyUp) {
|
||||
this.props.onKeyUp(e);
|
||||
}
|
||||
}
|
||||
|
||||
handleKeyPress = (e) => {
|
||||
if (this.props.onKeyPress && !this.props.disabled) {
|
||||
this.props.onKeyPress(e);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const style = {
|
||||
fontSize: `${this.props.size}px`,
|
||||
|
@ -98,8 +124,10 @@ export default class IconButton extends React.PureComponent {
|
|||
title={title}
|
||||
className={classes}
|
||||
onClick={this.handleClick}
|
||||
onKeyUp={this.props.onKeyUp}
|
||||
onKeyDown={this.props.onKeyDown}
|
||||
onMouseDown={this.handleMouseDown}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
onKeyUp={this.handleKeyUp}
|
||||
onKeyPress={this.handleKeyPress}
|
||||
onMouseEnter={this.props.onMouseEnter}
|
||||
onMouseLeave={this.props.onMouseLeave}
|
||||
tabIndex={tabIndex}
|
||||
|
@ -125,8 +153,10 @@ export default class IconButton extends React.PureComponent {
|
|||
title={title}
|
||||
className={classes}
|
||||
onClick={this.handleClick}
|
||||
onKeyUp={this.props.onKeyUp}
|
||||
onKeyDown={this.props.onKeyDown}
|
||||
onMouseDown={this.handleMouseDown}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
onKeyUp={this.handleKeyUp}
|
||||
onKeyPress={this.handleKeyPress}
|
||||
onMouseEnter={this.props.onMouseEnter}
|
||||
onMouseLeave={this.props.onMouseLeave}
|
||||
tabIndex={tabIndex}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import 'wicg-inert';
|
||||
import { injectIntl, FormattedMessage, defineMessages } from 'react-intl';
|
||||
import { connect } from 'react-redux';
|
||||
import { openModal } from '../actions/modal';
|
||||
|
@ -74,8 +75,31 @@ class ModalRoot extends React.PureComponent {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
handleKeyDown = (e) => {
|
||||
if (e.key === 'Tab') {
|
||||
const focusable = Array.from(this.node.querySelectorAll('button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])')).filter((x) => window.getComputedStyle(x).display !== 'none');
|
||||
const index = focusable.indexOf(e.target);
|
||||
|
||||
let element;
|
||||
|
||||
if (e.shiftKey) {
|
||||
element = focusable[index - 1] || focusable[focusable.length - 1];
|
||||
} else {
|
||||
element = focusable[index + 1] || focusable[0];
|
||||
}
|
||||
|
||||
if (element) {
|
||||
element.focus();
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener('keyup', this.handleKeyUp, false);
|
||||
window.addEventListener('keydown', this.handleKeyDown, false);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
|
@ -101,6 +125,7 @@ class ModalRoot extends React.PureComponent {
|
|||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('keyup', this.handleKeyUp);
|
||||
window.removeEventListener('keydown', this.handleKeyDown);
|
||||
}
|
||||
|
||||
getSiblings = () => {
|
||||
|
|
|
@ -213,6 +213,21 @@ class Status extends ImmutablePureComponent {
|
|||
this.props.OnOpenAudio(media, startTime);
|
||||
}
|
||||
|
||||
handleHotkeyOpenMedia = e => {
|
||||
const { onOpenMedia, onOpenVideo } = this.props;
|
||||
const status = this._properStatus();
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
if (status.get('media_attachments').size > 0) {
|
||||
if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
|
||||
onOpenVideo(status.getIn(['media_attachments', 0]), 0);
|
||||
} else {
|
||||
onOpenMedia(status.get('media_attachments'), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleHotkeyReply = e => {
|
||||
e.preventDefault();
|
||||
this.props.onReply(this._properStatus(), this.context.router.history);
|
||||
|
@ -461,6 +476,7 @@ class Status extends ImmutablePureComponent {
|
|||
moveDown: this.handleHotkeyMoveDown,
|
||||
toggleHidden: this.handleHotkeyToggleHidden,
|
||||
toggleSensitive: this.handleHotkeyToggleSensitive,
|
||||
openMedia: this.handleHotkeyOpenMedia,
|
||||
react: this.handleHotkeyReact,
|
||||
};
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ const mapDispatchToProps = (dispatch, { status, items }) => ({
|
|||
}) : openDropdownMenu(id, dropdownPlacement, keyboard));
|
||||
},
|
||||
onClose(id) {
|
||||
dispatch(closeModal());
|
||||
dispatch(closeModal('ACTIONS'));
|
||||
dispatch(closeDropdownMenu(id));
|
||||
},
|
||||
});
|
||||
|
|
|
@ -15,6 +15,8 @@ import UI from '../features/ui';
|
|||
// import Introduction from '../features/introduction';
|
||||
import { preload } from '../actions/preload';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { previewState as previewMediaState } from 'soapbox/features/ui/components/media_modal';
|
||||
import { previewState as previewVideoState } from 'soapbox/features/ui/components/video_modal';
|
||||
import ErrorBoundary from '../components/error_boundary';
|
||||
import { fetchInstance } from 'soapbox/actions/instance';
|
||||
import { fetchSoapboxConfig } from 'soapbox/actions/soapbox';
|
||||
|
@ -104,6 +106,10 @@ class SoapboxMount extends React.PureComponent {
|
|||
this.maybeUpdateMessages(prevProps);
|
||||
}
|
||||
|
||||
shouldUpdateScroll(_, { location }) {
|
||||
return location.state !== previewMediaState && location.state !== previewVideoState;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { me, themeCss, locale, customCss } = this.props;
|
||||
if (me === null) return null;
|
||||
|
@ -137,7 +143,7 @@ class SoapboxMount extends React.PureComponent {
|
|||
<meta name='theme-color' content={this.props.brandColor} />
|
||||
</Helmet>
|
||||
<BrowserRouter>
|
||||
<ScrollContext>
|
||||
<ScrollContext shouldUpdateScroll={this.shouldUpdateScroll}>
|
||||
<Switch>
|
||||
{!me && <Route exact path='/' component={PublicLayout} />}
|
||||
<Route exact path='/about/:slug?' component={PublicLayout} />
|
||||
|
|
|
@ -314,10 +314,6 @@ export default class ComposeForm extends ImmutablePureComponent {
|
|||
/>
|
||||
</div>
|
||||
|
||||
<div className='emoji-picker-wrapper'>
|
||||
<EmojiPickerDropdown onPickEmoji={this.handleEmojiPick} />
|
||||
</div>
|
||||
|
||||
<AutosuggestTextarea
|
||||
ref={(isModalOpen && shouldCondense) ? null : this.setAutosuggestTextarea}
|
||||
placeholder={intl.formatMessage(messages.placeholder)}
|
||||
|
@ -333,6 +329,7 @@ export default class ComposeForm extends ImmutablePureComponent {
|
|||
onPaste={onPaste}
|
||||
autoFocus={shouldAutoFocus}
|
||||
>
|
||||
<EmojiPickerDropdown onPickEmoji={this.handleEmojiPick} />
|
||||
{
|
||||
!condensed &&
|
||||
<div className='compose-form__modifiers'>
|
||||
|
|
|
@ -50,7 +50,7 @@ class PrivacyDropdownMenu extends React.PureComponent {
|
|||
const index = items.findIndex(item => {
|
||||
return (item.value === value);
|
||||
});
|
||||
let element;
|
||||
let element = null;
|
||||
|
||||
switch(e.key) {
|
||||
case 'Escape':
|
||||
|
@ -60,34 +60,32 @@ class PrivacyDropdownMenu extends React.PureComponent {
|
|||
this.handleClick(e);
|
||||
break;
|
||||
case 'ArrowDown':
|
||||
element = this.node.childNodes[index + 1];
|
||||
if (element) {
|
||||
element.focus();
|
||||
this.props.onChange(element.getAttribute('data-index'));
|
||||
}
|
||||
element = this.node.childNodes[index + 1] || this.node.firstChild;
|
||||
break;
|
||||
case 'ArrowUp':
|
||||
element = this.node.childNodes[index - 1];
|
||||
if (element) {
|
||||
element.focus();
|
||||
this.props.onChange(element.getAttribute('data-index'));
|
||||
element = this.node.childNodes[index - 1] || this.node.lastChild;
|
||||
break;
|
||||
case 'Tab':
|
||||
if (e.shiftKey) {
|
||||
element = this.node.childNodes[index - 1] || this.node.lastChild;
|
||||
} else {
|
||||
element = this.node.childNodes[index + 1] || this.node.firstChild;
|
||||
}
|
||||
break;
|
||||
case 'Home':
|
||||
element = this.node.firstChild;
|
||||
if (element) {
|
||||
element.focus();
|
||||
this.props.onChange(element.getAttribute('data-index'));
|
||||
}
|
||||
break;
|
||||
case 'End':
|
||||
element = this.node.lastChild;
|
||||
if (element) {
|
||||
element.focus();
|
||||
this.props.onChange(element.getAttribute('data-index'));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (element) {
|
||||
element.focus();
|
||||
this.props.onChange(element.getAttribute('data-index'));
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
handleClick = e => {
|
||||
|
@ -102,7 +100,7 @@ class PrivacyDropdownMenu extends React.PureComponent {
|
|||
componentDidMount() {
|
||||
document.addEventListener('click', this.handleDocumentClick, false);
|
||||
document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
|
||||
if (this.focusedItem) this.focusedItem.focus();
|
||||
if (this.focusedItem) this.focusedItem.focus({ preventScroll: true });
|
||||
this.setState({ mounted: true });
|
||||
}
|
||||
|
||||
|
@ -192,6 +190,9 @@ class PrivacyDropdown extends React.PureComponent {
|
|||
}
|
||||
} else {
|
||||
const { top } = target.getBoundingClientRect();
|
||||
if (this.state.open && this.activeElement) {
|
||||
this.activeElement.focus();
|
||||
}
|
||||
this.setState({ placement: top * 2 < innerHeight ? 'bottom' : 'top' });
|
||||
this.setState({ open: !this.state.open });
|
||||
}
|
||||
|
@ -214,7 +215,25 @@ class PrivacyDropdown extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
handleMouseDown = () => {
|
||||
if (!this.state.open) {
|
||||
this.activeElement = document.activeElement;
|
||||
}
|
||||
}
|
||||
|
||||
handleButtonKeyDown = (e) => {
|
||||
switch(e.key) {
|
||||
case ' ':
|
||||
case 'Enter':
|
||||
this.handleMouseDown();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
handleClose = () => {
|
||||
if (this.state.open && this.activeElement) {
|
||||
this.activeElement.focus();
|
||||
}
|
||||
this.setState({ open: false });
|
||||
}
|
||||
|
||||
|
@ -240,6 +259,8 @@ class PrivacyDropdown extends React.PureComponent {
|
|||
active={open}
|
||||
inverted
|
||||
onClick={this.handleToggle}
|
||||
onMouseDown={this.handleMouseDown}
|
||||
onKeyDown={this.handleButtonKeyDown}
|
||||
style={{ height: null, lineHeight: '27px' }}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -263,6 +263,21 @@ class Status extends ImmutablePureComponent {
|
|||
this.props.dispatch(openModal('VIDEO', { media, time }));
|
||||
}
|
||||
|
||||
handleHotkeyOpenMedia = e => {
|
||||
const { onOpenMedia, onOpenVideo } = this.props;
|
||||
const status = this._properStatus();
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
if (status.get('media_attachments').size > 0) {
|
||||
if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
|
||||
onOpenVideo(status.getIn(['media_attachments', 0]), 0);
|
||||
} else {
|
||||
onOpenMedia(status.get('media_attachments'), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleMuteClick = (account) => {
|
||||
this.props.dispatch(initMuteModal(account));
|
||||
}
|
||||
|
@ -548,6 +563,7 @@ class Status extends ImmutablePureComponent {
|
|||
openProfile: this.handleHotkeyOpenProfile,
|
||||
toggleHidden: this.handleHotkeyToggleHidden,
|
||||
toggleSensitive: this.handleHotkeyToggleSensitive,
|
||||
openMedia: this.handleHotkeyOpenMedia,
|
||||
react: this.handleHotkeyReact,
|
||||
};
|
||||
|
||||
|
|
|
@ -62,12 +62,8 @@ class HotkeysModal extends ImmutablePureComponent {
|
|||
<td><FormattedMessage id='keyboard_shortcuts.enter' defaultMessage='to open post' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>x</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.toggle_hidden' defaultMessage='to show/hide text behind CW' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>h</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.toggle_sensitivity' defaultMessage='to show/hide media' /></td>
|
||||
<td><kbd>a</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.open_media' defaultMessage='to open media' /></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -78,6 +74,14 @@ class HotkeysModal extends ImmutablePureComponent {
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><kbd>x</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.toggle_hidden' defaultMessage='to show/hide text behind CW' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>h</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.toggle_sensitivity' defaultMessage='to show/hide media' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>up</kbd>, <kbd>k</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.up' defaultMessage='to move up in the list' /></td>
|
||||
|
@ -106,10 +110,6 @@ class HotkeysModal extends ImmutablePureComponent {
|
|||
<td><kbd>esc</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.unfocus' defaultMessage='to un-focus compose textarea/search' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>g</kbd> + <kbd>h</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.home' defaultMessage='to open home timeline' /></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table>
|
||||
|
@ -119,6 +119,10 @@ class HotkeysModal extends ImmutablePureComponent {
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><kbd>g</kbd> + <kbd>h</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.home' defaultMessage='to open home timeline' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>g</kbd> + <kbd>n</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.notifications' defaultMessage='to open notifications column' /></td>
|
||||
|
|
|
@ -155,6 +155,7 @@ const keyMap = {
|
|||
goToRequests: 'g r',
|
||||
toggleHidden: 'x',
|
||||
toggleSensitive: 'h',
|
||||
openMedia: 'a',
|
||||
};
|
||||
|
||||
class SwitchingColumnsArea extends React.PureComponent {
|
||||
|
|
|
@ -461,7 +461,7 @@ class Video extends React.PureComponent {
|
|||
|
||||
<div className='video-player__buttons-bar'>
|
||||
<div className='video-player__buttons left'>
|
||||
<button type='button' aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} className='player-button' onClick={this.togglePlay}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
|
||||
<button type='button' aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} className='player-button' onClick={this.togglePlay} autoFocus={detailed}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
|
||||
<button type='button' aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} className='player-button' onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
|
||||
|
||||
<div className={classNames('video-player__volume', { active: this.state.hovered })} onMouseDown={this.handleVolumeMouseDown} ref={this.setVolumeRef}>
|
||||
|
|
|
@ -10,7 +10,7 @@ export default function modal(state = initialState, action) {
|
|||
case MODAL_OPEN:
|
||||
return { modalType: action.modalType, modalProps: action.modalProps };
|
||||
case MODAL_CLOSE:
|
||||
return initialState;
|
||||
return (action.modalType === undefined || action.modalType === state.modalType) ? initialState : state;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -221,6 +221,7 @@
|
|||
}
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&.active {
|
||||
border-bottom: 2px solid var(--primary-text-color);
|
||||
}
|
||||
|
|
|
@ -480,7 +480,8 @@
|
|||
color: var(--primary-text-color--faint);
|
||||
background: transparent;
|
||||
|
||||
&:hover {
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: hsla(var(--primary-text-color_hsl), 0.8);
|
||||
}
|
||||
|
||||
|
|
|
@ -62,9 +62,8 @@
|
|||
|
||||
.emoji-picker-dropdown {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
top: 10px;
|
||||
right: 5px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.compose-form__autosuggest-wrapper {
|
||||
|
@ -141,7 +140,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.emoji-picker-wrapper,
|
||||
.autosuggest-textarea__suggestions-wrapper {
|
||||
position: relative;
|
||||
height: 0;
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
&:hover,
|
||||
&:active,
|
||||
&:focus {
|
||||
color: var(--primary-text-color--faint);
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
|
@ -93,7 +93,7 @@
|
|||
&:hover,
|
||||
&:active,
|
||||
&:focus {
|
||||
color: var(--primary-text-color--faint);
|
||||
color: var(--primary-text-color);
|
||||
transition: color 200ms ease-out;
|
||||
}
|
||||
|
||||
|
@ -148,10 +148,6 @@
|
|||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.emoji-picker-wrapper {
|
||||
.emoji-picker-dropdown { top: 10px; }
|
||||
}
|
||||
|
||||
.compose-form {
|
||||
flex: 1 1;
|
||||
padding: 0 0 0 20px !important;
|
||||
|
|
|
@ -146,7 +146,8 @@
|
|||
"webpack-bundle-analyzer": "^4.0.0",
|
||||
"webpack-cli": "^3.3.2",
|
||||
"webpack-merge": "^5.2.0",
|
||||
"websocket.js": "^0.1.12"
|
||||
"websocket.js": "^0.1.12",
|
||||
"wicg-inert": "^3.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"axios-mock-adapter": "^1.18.1",
|
||||
|
|
|
@ -13062,6 +13062,11 @@ which@^2.0.1:
|
|||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
wicg-inert@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/wicg-inert/-/wicg-inert-3.1.1.tgz#b033fd4fbfb9e3fd709e5d84becbdf2e06e5c229"
|
||||
integrity sha512-PhBaNh8ur9Xm4Ggy4umelwNIP6pPP1bv3EaWaKqfb/QNme2rdLjm7wIInvV4WhxVHhzA4Spgw9qNSqWtB/ca2A==
|
||||
|
||||
wide-align@^1.1.0:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"
|
||||
|
|
Loading…
Reference in New Issue