forked from treehouse/mastodon
Merge pull request #1321 from ThibG/glitch-soc/merge-upstream
Merge upstream changesrebase/4.0.0rc2
commit
9c61dadc0d
|
@ -407,7 +407,7 @@ GEM
|
||||||
parallel (1.19.1)
|
parallel (1.19.1)
|
||||||
parallel_tests (2.32.0)
|
parallel_tests (2.32.0)
|
||||||
parallel
|
parallel
|
||||||
parser (2.7.1.0)
|
parser (2.7.1.1)
|
||||||
ast (~> 2.4.0)
|
ast (~> 2.4.0)
|
||||||
parslet (1.8.2)
|
parslet (1.8.2)
|
||||||
pastel (0.7.3)
|
pastel (0.7.3)
|
||||||
|
@ -492,9 +492,9 @@ GEM
|
||||||
rdf (~> 3.1)
|
rdf (~> 3.1)
|
||||||
redcarpet (3.5.0)
|
redcarpet (3.5.0)
|
||||||
redis (4.1.3)
|
redis (4.1.3)
|
||||||
redis-actionpack (5.0.2)
|
redis-actionpack (5.2.0)
|
||||||
actionpack (>= 4.0, < 6)
|
actionpack (>= 5, < 7)
|
||||||
redis-rack (>= 1, < 3)
|
redis-rack (>= 2.1.0, < 3)
|
||||||
redis-store (>= 1.1.0, < 2)
|
redis-store (>= 1.1.0, < 2)
|
||||||
redis-activesupport (5.0.4)
|
redis-activesupport (5.0.4)
|
||||||
activesupport (>= 3, < 6)
|
activesupport (>= 3, < 6)
|
||||||
|
|
|
@ -68,20 +68,14 @@ class DropdownMenu extends React.PureComponent {
|
||||||
handleKeyDown = e => {
|
handleKeyDown = e => {
|
||||||
const items = Array.from(this.node.getElementsByTagName('a'));
|
const items = Array.from(this.node.getElementsByTagName('a'));
|
||||||
const index = items.indexOf(document.activeElement);
|
const index = items.indexOf(document.activeElement);
|
||||||
let element;
|
let element = null;
|
||||||
|
|
||||||
switch(e.key) {
|
switch(e.key) {
|
||||||
case 'ArrowDown':
|
case 'ArrowDown':
|
||||||
element = items[index+1];
|
element = items[index+1] || items[0];
|
||||||
if (element) {
|
|
||||||
element.focus();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'ArrowUp':
|
case 'ArrowUp':
|
||||||
element = items[index-1];
|
element = items[index-1] || items[items.length-1];
|
||||||
if (element) {
|
|
||||||
element.focus();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'Tab':
|
case 'Tab':
|
||||||
if (e.shiftKey) {
|
if (e.shiftKey) {
|
||||||
|
@ -89,28 +83,23 @@ class DropdownMenu extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
element = items[index+1] || items[0];
|
element = items[index+1] || items[0];
|
||||||
}
|
}
|
||||||
if (element) {
|
|
||||||
element.focus();
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'Home':
|
case 'Home':
|
||||||
element = items[0];
|
element = items[0];
|
||||||
if (element) {
|
|
||||||
element.focus();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'End':
|
case 'End':
|
||||||
element = items[items.length-1];
|
element = items[items.length-1];
|
||||||
if (element) {
|
|
||||||
element.focus();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
this.props.onClose();
|
this.props.onClose();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (element) {
|
||||||
|
element.focus();
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleItemKeyPress = e => {
|
handleItemKeyPress = e => {
|
||||||
|
|
|
@ -372,8 +372,8 @@ class Status extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handleOpenVideo = (media, startTime) => {
|
handleOpenVideo = (media, options) => {
|
||||||
this.props.onOpenVideo(media, startTime);
|
this.props.onOpenVideo(media, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleHotkeyOpenMedia = e => {
|
handleHotkeyOpenMedia = e => {
|
||||||
|
@ -385,7 +385,7 @@ class Status extends ImmutablePureComponent {
|
||||||
if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
|
if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
|
||||||
// TODO: toggle play/paused?
|
// TODO: toggle play/paused?
|
||||||
} else if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
|
} else if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
|
||||||
onOpenVideo(status.getIn(['media_attachments', 0]), 0);
|
onOpenVideo(status.getIn(['media_attachments', 0]), { startTime: 0 });
|
||||||
} else {
|
} else {
|
||||||
onOpenMedia(status.get('media_attachments'), 0);
|
onOpenMedia(status.get('media_attachments'), 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,8 +178,8 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({
|
||||||
dispatch(openModal('MEDIA', { media, index }));
|
dispatch(openModal('MEDIA', { media, index }));
|
||||||
},
|
},
|
||||||
|
|
||||||
onOpenVideo (media, time) {
|
onOpenVideo (media, options) {
|
||||||
dispatch(openModal('VIDEO', { media, time }));
|
dispatch(openModal('VIDEO', { media, options }));
|
||||||
},
|
},
|
||||||
|
|
||||||
onBlock (status) {
|
onBlock (status) {
|
||||||
|
|
|
@ -106,7 +106,7 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
|
||||||
const index = items.findIndex(item => {
|
const index = items.findIndex(item => {
|
||||||
return (item.name === name);
|
return (item.name === name);
|
||||||
});
|
});
|
||||||
let element;
|
let element = null;
|
||||||
|
|
||||||
switch(e.key) {
|
switch(e.key) {
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
|
@ -117,18 +117,10 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
|
||||||
this.handleClick(e);
|
this.handleClick(e);
|
||||||
break;
|
break;
|
||||||
case 'ArrowDown':
|
case 'ArrowDown':
|
||||||
element = this.node.childNodes[index + 1];
|
element = this.node.childNodes[index + 1] || this.node.firstChild;
|
||||||
if (element) {
|
|
||||||
element.focus();
|
|
||||||
this.handleChange(element.getAttribute('data-index'));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'ArrowUp':
|
case 'ArrowUp':
|
||||||
element = this.node.childNodes[index - 1];
|
element = this.node.childNodes[index - 1] || this.node.lastChild;
|
||||||
if (element) {
|
|
||||||
element.focus();
|
|
||||||
this.handleChange(element.getAttribute('data-index'));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'Tab':
|
case 'Tab':
|
||||||
if (e.shiftKey) {
|
if (e.shiftKey) {
|
||||||
|
@ -136,28 +128,21 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
|
||||||
} else {
|
} else {
|
||||||
element = this.node.childNodes[index + 1] || this.node.firstChild;
|
element = this.node.childNodes[index + 1] || this.node.firstChild;
|
||||||
}
|
}
|
||||||
if (element) {
|
|
||||||
element.focus();
|
|
||||||
this.handleChange(element.getAttribute('data-index'));
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'Home':
|
case 'Home':
|
||||||
element = this.node.firstChild;
|
element = this.node.firstChild;
|
||||||
if (element) {
|
|
||||||
element.focus();
|
|
||||||
this.handleChange(element.getAttribute('data-index'));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'End':
|
case 'End':
|
||||||
element = this.node.lastChild;
|
element = this.node.lastChild;
|
||||||
if (element) {
|
|
||||||
element.focus();
|
|
||||||
this.handleChange(element.getAttribute('data-index'));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (element) {
|
||||||
|
element.focus();
|
||||||
|
this.handleChange(element.getAttribute('data-index'));
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setFocusRef = c => {
|
setFocusRef = c => {
|
||||||
|
|
|
@ -66,8 +66,8 @@ export default class DetailedStatus extends ImmutablePureComponent {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleOpenVideo = (media, startTime) => {
|
handleOpenVideo = (media, options) => {
|
||||||
this.props.onOpenVideo(media, startTime);
|
this.props.onOpenVideo(media, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
_measureHeight (heightJustChanged) {
|
_measureHeight (heightJustChanged) {
|
||||||
|
|
|
@ -130,8 +130,8 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||||
dispatch(openModal('MEDIA', { media, index }));
|
dispatch(openModal('MEDIA', { media, index }));
|
||||||
},
|
},
|
||||||
|
|
||||||
onOpenVideo (media, time) {
|
onOpenVideo (media, options) {
|
||||||
dispatch(openModal('VIDEO', { media, time }));
|
dispatch(openModal('VIDEO', { media, options }));
|
||||||
},
|
},
|
||||||
|
|
||||||
onBlock (status) {
|
onBlock (status) {
|
||||||
|
|
|
@ -316,8 +316,8 @@ class Status extends ImmutablePureComponent {
|
||||||
this.props.dispatch(openModal('MEDIA', { media, index }));
|
this.props.dispatch(openModal('MEDIA', { media, index }));
|
||||||
}
|
}
|
||||||
|
|
||||||
handleOpenVideo = (media, time) => {
|
handleOpenVideo = (media, options) => {
|
||||||
this.props.dispatch(openModal('VIDEO', { media, time }));
|
this.props.dispatch(openModal('VIDEO', { media, options }));
|
||||||
}
|
}
|
||||||
|
|
||||||
handleHotkeyOpenMedia = e => {
|
handleHotkeyOpenMedia = e => {
|
||||||
|
@ -329,7 +329,7 @@ class Status extends ImmutablePureComponent {
|
||||||
if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
|
if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
|
||||||
// TODO: toggle play/paused?
|
// TODO: toggle play/paused?
|
||||||
} else if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
|
} else if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
|
||||||
this.handleOpenVideo(status.getIn(['media_attachments', 0]), 0);
|
this.handleOpenVideo(status.getIn(['media_attachments', 0]), { startTime: 0 });
|
||||||
} else {
|
} else {
|
||||||
this.handleOpenMedia(status.get('media_attachments'), 0);
|
this.handleOpenMedia(status.get('media_attachments'), 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,11 @@ export default class VideoModal extends ImmutablePureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
media: ImmutablePropTypes.map.isRequired,
|
media: ImmutablePropTypes.map.isRequired,
|
||||||
status: ImmutablePropTypes.map,
|
status: ImmutablePropTypes.map,
|
||||||
time: PropTypes.number,
|
options: PropTypes.shape({
|
||||||
|
startTime: PropTypes.number,
|
||||||
|
autoPlay: PropTypes.bool,
|
||||||
|
defaultVolume: PropTypes.number,
|
||||||
|
}),
|
||||||
onClose: PropTypes.func.isRequired,
|
onClose: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -28,7 +32,8 @@ export default class VideoModal extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { media, status, time, onClose } = this.props;
|
const { media, status, onClose } = this.props;
|
||||||
|
const options = this.props.options || {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='modal-root__modal video-modal'>
|
<div className='modal-root__modal video-modal'>
|
||||||
|
@ -37,7 +42,9 @@ export default class VideoModal extends ImmutablePureComponent {
|
||||||
preview={media.get('preview_url')}
|
preview={media.get('preview_url')}
|
||||||
blurhash={media.get('blurhash')}
|
blurhash={media.get('blurhash')}
|
||||||
src={media.get('url')}
|
src={media.get('url')}
|
||||||
startTime={time}
|
startTime={options.startTime}
|
||||||
|
autoPlay={options.autoPlay}
|
||||||
|
defaultVolume={options.defaultVolume}
|
||||||
onCloseVideo={onClose}
|
onCloseVideo={onClose}
|
||||||
detailed
|
detailed
|
||||||
alt={media.get('description')}
|
alt={media.get('description')}
|
||||||
|
|
|
@ -111,6 +111,8 @@ class Video extends React.PureComponent {
|
||||||
preventPlayback: PropTypes.bool,
|
preventPlayback: PropTypes.bool,
|
||||||
blurhash: PropTypes.string,
|
blurhash: PropTypes.string,
|
||||||
link: PropTypes.node,
|
link: PropTypes.node,
|
||||||
|
autoPlay: PropTypes.bool,
|
||||||
|
defaultVolume: PropTypes.number,
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
|
@ -360,6 +362,13 @@ class Video extends React.PureComponent {
|
||||||
handleLoadedData = () => {
|
handleLoadedData = () => {
|
||||||
if (this.props.startTime) {
|
if (this.props.startTime) {
|
||||||
this.video.currentTime = this.props.startTime;
|
this.video.currentTime = this.props.startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.defaultVolume !== undefined) {
|
||||||
|
this.video.volume = this.props.defaultVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.autoPlay) {
|
||||||
this.video.play();
|
this.video.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -386,8 +395,14 @@ class Video extends React.PureComponent {
|
||||||
height,
|
height,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
startTime: this.video.currentTime,
|
||||||
|
autoPlay: !this.state.paused,
|
||||||
|
defaultVolume: this.state.volume,
|
||||||
|
};
|
||||||
|
|
||||||
this.video.pause();
|
this.video.pause();
|
||||||
this.props.onOpenVideo(media, this.video.currentTime);
|
this.props.onOpenVideo(media, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleCloseVideo = () => {
|
handleCloseVideo = () => {
|
||||||
|
|
|
@ -691,3 +691,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gifv {
|
||||||
|
video {
|
||||||
|
max-width: 100vw;
|
||||||
|
max-height: 80vh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -138,7 +138,7 @@ const resizeImage = (img, type = 'image/png') => new Promise((resolve, reject) =
|
||||||
.catch(reject);
|
.catch(reject);
|
||||||
});
|
});
|
||||||
|
|
||||||
export default inputFile => new Promise((resolve, reject) => {
|
export default inputFile => new Promise((resolve) => {
|
||||||
if (!inputFile.type.match(/image.*/) || inputFile.type === 'image/gif') {
|
if (!inputFile.type.match(/image.*/) || inputFile.type === 'image/gif') {
|
||||||
resolve(inputFile);
|
resolve(inputFile);
|
||||||
return;
|
return;
|
||||||
|
@ -153,5 +153,5 @@ export default inputFile => new Promise((resolve, reject) => {
|
||||||
resizeImage(img, inputFile.type)
|
resizeImage(img, inputFile.type)
|
||||||
.then(resolve)
|
.then(resolve)
|
||||||
.catch(() => resolve(inputFile));
|
.catch(() => resolve(inputFile));
|
||||||
}).catch(reject);
|
}).catch(() => resolve(inputFile));
|
||||||
});
|
});
|
||||||
|
|
|
@ -68,20 +68,14 @@ class DropdownMenu extends React.PureComponent {
|
||||||
handleKeyDown = e => {
|
handleKeyDown = e => {
|
||||||
const items = Array.from(this.node.getElementsByTagName('a'));
|
const items = Array.from(this.node.getElementsByTagName('a'));
|
||||||
const index = items.indexOf(document.activeElement);
|
const index = items.indexOf(document.activeElement);
|
||||||
let element;
|
let element = null;
|
||||||
|
|
||||||
switch(e.key) {
|
switch(e.key) {
|
||||||
case 'ArrowDown':
|
case 'ArrowDown':
|
||||||
element = items[index+1];
|
element = items[index+1] || items[0];
|
||||||
if (element) {
|
|
||||||
element.focus();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'ArrowUp':
|
case 'ArrowUp':
|
||||||
element = items[index-1];
|
element = items[index-1] || items[items.length-1];
|
||||||
if (element) {
|
|
||||||
element.focus();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'Tab':
|
case 'Tab':
|
||||||
if (e.shiftKey) {
|
if (e.shiftKey) {
|
||||||
|
@ -89,28 +83,23 @@ class DropdownMenu extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
element = items[index+1] || items[0];
|
element = items[index+1] || items[0];
|
||||||
}
|
}
|
||||||
if (element) {
|
|
||||||
element.focus();
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'Home':
|
case 'Home':
|
||||||
element = items[0];
|
element = items[0];
|
||||||
if (element) {
|
|
||||||
element.focus();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'End':
|
case 'End':
|
||||||
element = items[items.length-1];
|
element = items[items.length-1];
|
||||||
if (element) {
|
|
||||||
element.focus();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
this.props.onClose();
|
this.props.onClose();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (element) {
|
||||||
|
element.focus();
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleItemKeyPress = e => {
|
handleItemKeyPress = e => {
|
||||||
|
|
|
@ -176,8 +176,8 @@ class Status extends ImmutablePureComponent {
|
||||||
return <div className='audio-player' style={{ height: '110px' }} />;
|
return <div className='audio-player' style={{ height: '110px' }} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleOpenVideo = (media, startTime) => {
|
handleOpenVideo = (media, options) => {
|
||||||
this.props.onOpenVideo(media, startTime);
|
this.props.onOpenVideo(media, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleHotkeyOpenMedia = e => {
|
handleHotkeyOpenMedia = e => {
|
||||||
|
@ -190,7 +190,7 @@ class Status extends ImmutablePureComponent {
|
||||||
if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
|
if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
|
||||||
// TODO: toggle play/paused?
|
// TODO: toggle play/paused?
|
||||||
} else if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
|
} else if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
|
||||||
onOpenVideo(status.getIn(['media_attachments', 0]), 0);
|
onOpenVideo(status.getIn(['media_attachments', 0]), { startTime: 0 });
|
||||||
} else {
|
} else {
|
||||||
onOpenMedia(status.get('media_attachments'), 0);
|
onOpenMedia(status.get('media_attachments'), 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,8 +150,8 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||||
dispatch(openModal('MEDIA', { media, index }));
|
dispatch(openModal('MEDIA', { media, index }));
|
||||||
},
|
},
|
||||||
|
|
||||||
onOpenVideo (media, time) {
|
onOpenVideo (media, options) {
|
||||||
dispatch(openModal('VIDEO', { media, time }));
|
dispatch(openModal('VIDEO', { media, options }));
|
||||||
},
|
},
|
||||||
|
|
||||||
onBlock (status) {
|
onBlock (status) {
|
||||||
|
|
|
@ -50,7 +50,7 @@ class PrivacyDropdownMenu extends React.PureComponent {
|
||||||
const index = items.findIndex(item => {
|
const index = items.findIndex(item => {
|
||||||
return (item.value === value);
|
return (item.value === value);
|
||||||
});
|
});
|
||||||
let element;
|
let element = null;
|
||||||
|
|
||||||
switch(e.key) {
|
switch(e.key) {
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
|
@ -60,18 +60,10 @@ class PrivacyDropdownMenu extends React.PureComponent {
|
||||||
this.handleClick(e);
|
this.handleClick(e);
|
||||||
break;
|
break;
|
||||||
case 'ArrowDown':
|
case 'ArrowDown':
|
||||||
element = this.node.childNodes[index + 1];
|
element = this.node.childNodes[index + 1] || this.node.firstChild;
|
||||||
if (element) {
|
|
||||||
element.focus();
|
|
||||||
this.props.onChange(element.getAttribute('data-index'));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'ArrowUp':
|
case 'ArrowUp':
|
||||||
element = this.node.childNodes[index - 1];
|
element = this.node.childNodes[index - 1] || this.node.lastChild;
|
||||||
if (element) {
|
|
||||||
element.focus();
|
|
||||||
this.props.onChange(element.getAttribute('data-index'));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'Tab':
|
case 'Tab':
|
||||||
if (e.shiftKey) {
|
if (e.shiftKey) {
|
||||||
|
@ -79,28 +71,21 @@ class PrivacyDropdownMenu extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
element = this.node.childNodes[index + 1] || this.node.firstChild;
|
element = this.node.childNodes[index + 1] || this.node.firstChild;
|
||||||
}
|
}
|
||||||
if (element) {
|
|
||||||
element.focus();
|
|
||||||
this.props.onChange(element.getAttribute('data-index'));
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'Home':
|
case 'Home':
|
||||||
element = this.node.firstChild;
|
element = this.node.firstChild;
|
||||||
if (element) {
|
|
||||||
element.focus();
|
|
||||||
this.props.onChange(element.getAttribute('data-index'));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'End':
|
case 'End':
|
||||||
element = this.node.lastChild;
|
element = this.node.lastChild;
|
||||||
if (element) {
|
|
||||||
element.focus();
|
|
||||||
this.props.onChange(element.getAttribute('data-index'));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (element) {
|
||||||
|
element.focus();
|
||||||
|
this.props.onChange(element.getAttribute('data-index'));
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleClick = e => {
|
handleClick = e => {
|
||||||
|
|
|
@ -48,8 +48,8 @@ export default class DetailedStatus extends ImmutablePureComponent {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleOpenVideo = (media, startTime) => {
|
handleOpenVideo = (media, options) => {
|
||||||
this.props.onOpenVideo(media, startTime);
|
this.props.onOpenVideo(media, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleExpandedToggle = () => {
|
handleExpandedToggle = () => {
|
||||||
|
|
|
@ -129,8 +129,8 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||||
dispatch(openModal('MEDIA', { media, index }));
|
dispatch(openModal('MEDIA', { media, index }));
|
||||||
},
|
},
|
||||||
|
|
||||||
onOpenVideo (media, time) {
|
onOpenVideo (media, options) {
|
||||||
dispatch(openModal('VIDEO', { media, time }));
|
dispatch(openModal('VIDEO', { media, options }));
|
||||||
},
|
},
|
||||||
|
|
||||||
onBlock (status) {
|
onBlock (status) {
|
||||||
|
|
|
@ -277,8 +277,8 @@ class Status extends ImmutablePureComponent {
|
||||||
this.props.dispatch(openModal('MEDIA', { media, index }));
|
this.props.dispatch(openModal('MEDIA', { media, index }));
|
||||||
}
|
}
|
||||||
|
|
||||||
handleOpenVideo = (media, time) => {
|
handleOpenVideo = (media, options) => {
|
||||||
this.props.dispatch(openModal('VIDEO', { media, time }));
|
this.props.dispatch(openModal('VIDEO', { media, options }));
|
||||||
}
|
}
|
||||||
|
|
||||||
handleHotkeyOpenMedia = e => {
|
handleHotkeyOpenMedia = e => {
|
||||||
|
@ -290,7 +290,7 @@ class Status extends ImmutablePureComponent {
|
||||||
if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
|
if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
|
||||||
// TODO: toggle play/paused?
|
// TODO: toggle play/paused?
|
||||||
} else if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
|
} else if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
|
||||||
this.handleOpenVideo(status.getIn(['media_attachments', 0]), 0);
|
this.handleOpenVideo(status.getIn(['media_attachments', 0]), { startTime: 0 });
|
||||||
} else {
|
} else {
|
||||||
this.handleOpenMedia(status.get('media_attachments'), 0);
|
this.handleOpenMedia(status.get('media_attachments'), 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,11 @@ export default class VideoModal extends ImmutablePureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
media: ImmutablePropTypes.map.isRequired,
|
media: ImmutablePropTypes.map.isRequired,
|
||||||
status: ImmutablePropTypes.map,
|
status: ImmutablePropTypes.map,
|
||||||
time: PropTypes.number,
|
options: PropTypes.shape({
|
||||||
|
startTime: PropTypes.number,
|
||||||
|
autoPlay: PropTypes.bool,
|
||||||
|
defaultVolume: PropTypes.number,
|
||||||
|
}),
|
||||||
onClose: PropTypes.func.isRequired,
|
onClose: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -52,7 +56,8 @@ export default class VideoModal extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { media, status, time, onClose } = this.props;
|
const { media, status, onClose } = this.props;
|
||||||
|
const options = this.props.options || {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='modal-root__modal video-modal'>
|
<div className='modal-root__modal video-modal'>
|
||||||
|
@ -61,7 +66,9 @@ export default class VideoModal extends ImmutablePureComponent {
|
||||||
preview={media.get('preview_url')}
|
preview={media.get('preview_url')}
|
||||||
blurhash={media.get('blurhash')}
|
blurhash={media.get('blurhash')}
|
||||||
src={media.get('url')}
|
src={media.get('url')}
|
||||||
startTime={time}
|
startTime={options.startTime}
|
||||||
|
autoPlay={options.autoPlay}
|
||||||
|
defaultVolume={options.defaultVolume}
|
||||||
onCloseVideo={onClose}
|
onCloseVideo={onClose}
|
||||||
detailed
|
detailed
|
||||||
alt={media.get('description')}
|
alt={media.get('description')}
|
||||||
|
|
|
@ -109,6 +109,8 @@ class Video extends React.PureComponent {
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
blurhash: PropTypes.string,
|
blurhash: PropTypes.string,
|
||||||
link: PropTypes.node,
|
link: PropTypes.node,
|
||||||
|
autoPlay: PropTypes.bool,
|
||||||
|
defaultVolume: PropTypes.number,
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
|
@ -367,6 +369,13 @@ class Video extends React.PureComponent {
|
||||||
handleLoadedData = () => {
|
handleLoadedData = () => {
|
||||||
if (this.props.startTime) {
|
if (this.props.startTime) {
|
||||||
this.video.currentTime = this.props.startTime;
|
this.video.currentTime = this.props.startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.defaultVolume !== undefined) {
|
||||||
|
this.video.volume = this.props.defaultVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.autoPlay) {
|
||||||
this.video.play();
|
this.video.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -393,8 +402,14 @@ class Video extends React.PureComponent {
|
||||||
height,
|
height,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
startTime: this.video.currentTime,
|
||||||
|
autoPlay: !this.state.paused,
|
||||||
|
defaultVolume: this.state.volume,
|
||||||
|
};
|
||||||
|
|
||||||
this.video.pause();
|
this.video.pause();
|
||||||
this.props.onOpenVideo(media, this.video.currentTime);
|
this.props.onOpenVideo(media, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleCloseVideo = () => {
|
handleCloseVideo = () => {
|
||||||
|
|
|
@ -138,7 +138,7 @@ const resizeImage = (img, type = 'image/png') => new Promise((resolve, reject) =
|
||||||
.catch(reject);
|
.catch(reject);
|
||||||
});
|
});
|
||||||
|
|
||||||
export default inputFile => new Promise((resolve, reject) => {
|
export default inputFile => new Promise((resolve) => {
|
||||||
if (!inputFile.type.match(/image.*/) || inputFile.type === 'image/gif') {
|
if (!inputFile.type.match(/image.*/) || inputFile.type === 'image/gif') {
|
||||||
resolve(inputFile);
|
resolve(inputFile);
|
||||||
return;
|
return;
|
||||||
|
@ -153,5 +153,5 @@ export default inputFile => new Promise((resolve, reject) => {
|
||||||
resizeImage(img, inputFile.type)
|
resizeImage(img, inputFile.type)
|
||||||
.then(resolve)
|
.then(resolve)
|
||||||
.catch(() => resolve(inputFile));
|
.catch(() => resolve(inputFile));
|
||||||
}).catch(reject);
|
}).catch(() => resolve(inputFile));
|
||||||
});
|
});
|
||||||
|
|
|
@ -5575,6 +5575,13 @@ a.status-card.compact:hover {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gifv {
|
||||||
|
video {
|
||||||
|
max-width: 100vw;
|
||||||
|
max-height: 80vh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.directory {
|
.directory {
|
||||||
&__list {
|
&__list {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -27,7 +27,7 @@ class Relay < ApplicationRecord
|
||||||
payload = Oj.dump(follow_activity(activity_id))
|
payload = Oj.dump(follow_activity(activity_id))
|
||||||
|
|
||||||
update!(state: :pending, follow_activity_id: activity_id)
|
update!(state: :pending, follow_activity_id: activity_id)
|
||||||
DeliveryFailureTracker.track_success!(inbox_url)
|
DeliveryFailureTracker.reset!(inbox_url)
|
||||||
ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
|
ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ class Relay < ApplicationRecord
|
||||||
payload = Oj.dump(unfollow_activity(activity_id))
|
payload = Oj.dump(unfollow_activity(activity_id))
|
||||||
|
|
||||||
update!(state: :idle, follow_activity_id: nil)
|
update!(state: :idle, follow_activity_id: nil)
|
||||||
DeliveryFailureTracker.track_success!(inbox_url)
|
DeliveryFailureTracker.reset!(inbox_url)
|
||||||
ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
|
ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -163,7 +163,7 @@
|
||||||
"tesseract.js": "^2.0.0-alpha.16",
|
"tesseract.js": "^2.0.0-alpha.16",
|
||||||
"throng": "^4.0.0",
|
"throng": "^4.0.0",
|
||||||
"tiny-queue": "^0.2.1",
|
"tiny-queue": "^0.2.1",
|
||||||
"uuid": "^7.0.2",
|
"uuid": "^7.0.3",
|
||||||
"wavesurfer.js": "^3.3.1",
|
"wavesurfer.js": "^3.3.1",
|
||||||
"webpack": "^4.42.1",
|
"webpack": "^4.42.1",
|
||||||
"webpack-assets-manifest": "^3.1.1",
|
"webpack-assets-manifest": "^3.1.1",
|
||||||
|
|
37
yarn.lock
37
yarn.lock
|
@ -5065,12 +5065,12 @@ globby@^7.1.1:
|
||||||
slash "^1.0.0"
|
slash "^1.0.0"
|
||||||
|
|
||||||
globule@^1.0.0:
|
globule@^1.0.0:
|
||||||
version "1.2.1"
|
version "1.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d"
|
resolved "https://registry.yarnpkg.com/globule/-/globule-1.3.1.tgz#90a25338f22b7fbeb527cee63c629aea754d33b9"
|
||||||
integrity sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==
|
integrity sha512-OVyWOHgw29yosRHCHo7NncwR1hW5ew0W/UrvtwvjefVJeQ26q4/8r8FmPsSF1hJ93IgWkyv16pCTz6WblMzm/g==
|
||||||
dependencies:
|
dependencies:
|
||||||
glob "~7.1.1"
|
glob "~7.1.1"
|
||||||
lodash "~4.17.10"
|
lodash "~4.17.12"
|
||||||
minimatch "~3.0.2"
|
minimatch "~3.0.2"
|
||||||
|
|
||||||
gonzales-pe-sl@^4.2.3:
|
gonzales-pe-sl@^4.2.3:
|
||||||
|
@ -6922,7 +6922,7 @@ lodash.uniq@^4.5.0:
|
||||||
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
||||||
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
|
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
|
||||||
|
|
||||||
lodash@^4.0.0, lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.3.0, lodash@~4.17.10:
|
lodash@^4.0.0, lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.3.0, lodash@~4.17.12:
|
||||||
version "4.17.15"
|
version "4.17.15"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
||||||
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
|
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
|
||||||
|
@ -10023,16 +10023,11 @@ side-channel@^1.0.2:
|
||||||
es-abstract "^1.17.0-next.1"
|
es-abstract "^1.17.0-next.1"
|
||||||
object-inspect "^1.7.0"
|
object-inspect "^1.7.0"
|
||||||
|
|
||||||
signal-exit@^3.0.0:
|
signal-exit@^3.0.0, signal-exit@^3.0.2:
|
||||||
version "3.0.3"
|
version "3.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
|
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
|
||||||
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
|
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
|
||||||
|
|
||||||
signal-exit@^3.0.2:
|
|
||||||
version "3.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
|
|
||||||
integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
|
|
||||||
|
|
||||||
simple-swizzle@^0.2.2:
|
simple-swizzle@^0.2.2:
|
||||||
version "0.2.2"
|
version "0.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
|
resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
|
||||||
|
@ -10041,9 +10036,9 @@ simple-swizzle@^0.2.2:
|
||||||
is-arrayish "^0.3.1"
|
is-arrayish "^0.3.1"
|
||||||
|
|
||||||
sisteransi@^1.0.0:
|
sisteransi@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.0.tgz#77d9622ff909080f1c19e5f4a1df0c1b0a27b88c"
|
resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed"
|
||||||
integrity sha512-N+z4pHB4AmUv0SjveWRd6q1Nj5w62m5jodv+GD8lvmbY/83T/rpbJGZOnK5T149OldDj4Db07BSv9xY4K6NTPQ==
|
integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==
|
||||||
|
|
||||||
slash@^1.0.0:
|
slash@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
|
@ -10366,9 +10361,9 @@ stream-http@^2.7.2:
|
||||||
xtend "^4.0.0"
|
xtend "^4.0.0"
|
||||||
|
|
||||||
stream-shift@^1.0.0:
|
stream-shift@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952"
|
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
|
||||||
integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=
|
integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==
|
||||||
|
|
||||||
strict-uri-encode@^1.0.0:
|
strict-uri-encode@^1.0.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
|
@ -11147,10 +11142,10 @@ uuid@^3.0.1, uuid@^3.3.2:
|
||||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
|
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
|
||||||
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
|
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
|
||||||
|
|
||||||
uuid@^7.0.2:
|
uuid@^7.0.3:
|
||||||
version "7.0.2"
|
version "7.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.2.tgz#7ff5c203467e91f5e0d85cfcbaaf7d2ebbca9be6"
|
resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b"
|
||||||
integrity sha512-vy9V/+pKG+5ZTYKf+VcphF5Oc6EFiu3W8Nv3P3zIh0EqVI80ZxOzuPfe9EHjkFNvf8+xuTHVeei4Drydlx4zjw==
|
integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==
|
||||||
|
|
||||||
v8-compile-cache@2.0.3, v8-compile-cache@^2.0.3:
|
v8-compile-cache@2.0.3, v8-compile-cache@^2.0.3:
|
||||||
version "2.0.3"
|
version "2.0.3"
|
||||||
|
|
Loading…
Reference in New Issue