@@ -407,7 +407,7 @@ GEM | |||
parallel (1.19.1) | |||
parallel_tests (2.32.0) | |||
parallel | |||
parser (2.7.1.0) | |||
parser (2.7.1.1) | |||
ast (~> 2.4.0) | |||
parslet (1.8.2) | |||
pastel (0.7.3) | |||
@@ -492,9 +492,9 @@ GEM | |||
rdf (~> 3.1) | |||
redcarpet (3.5.0) | |||
redis (4.1.3) | |||
redis-actionpack (5.0.2) | |||
actionpack (>= 4.0, < 6) | |||
redis-rack (>= 1, < 3) | |||
redis-actionpack (5.2.0) | |||
actionpack (>= 5, < 7) | |||
redis-rack (>= 2.1.0, < 3) | |||
redis-store (>= 1.1.0, < 2) | |||
redis-activesupport (5.0.4) | |||
activesupport (>= 3, < 6) | |||
@@ -68,20 +68,14 @@ 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) { | |||
@@ -89,28 +83,23 @@ class DropdownMenu extends React.PureComponent { | |||
} else { | |||
element = items[index+1] || items[0]; | |||
} | |||
if (element) { | |||
element.focus(); | |||
e.preventDefault(); | |||
e.stopPropagation(); | |||
} | |||
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(); | |||
} | |||
} | |||
handleItemKeyPress = e => { | |||
@@ -176,8 +176,8 @@ class Status extends ImmutablePureComponent { | |||
return <div className='audio-player' style={{ height: '110px' }} />; | |||
} | |||
handleOpenVideo = (media, startTime) => { | |||
this.props.onOpenVideo(media, startTime); | |||
handleOpenVideo = (media, options) => { | |||
this.props.onOpenVideo(media, options); | |||
} | |||
handleHotkeyOpenMedia = e => { | |||
@@ -190,7 +190,7 @@ class Status extends ImmutablePureComponent { | |||
if (status.getIn(['media_attachments', 0, 'type']) === 'audio') { | |||
// TODO: toggle play/paused? | |||
} 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 { | |||
onOpenMedia(status.get('media_attachments'), 0); | |||
} | |||
@@ -150,8 +150,8 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ | |||
dispatch(openModal('MEDIA', { media, index })); | |||
}, | |||
onOpenVideo (media, time) { | |||
dispatch(openModal('VIDEO', { media, time })); | |||
onOpenVideo (media, options) { | |||
dispatch(openModal('VIDEO', { media, options })); | |||
}, | |||
onBlock (status) { | |||
@@ -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,18 +60,10 @@ 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) { | |||
@@ -79,28 +71,21 @@ class PrivacyDropdownMenu extends React.PureComponent { | |||
} else { | |||
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; | |||
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 => { | |||
@@ -48,8 +48,8 @@ export default class DetailedStatus extends ImmutablePureComponent { | |||
e.stopPropagation(); | |||
} | |||
handleOpenVideo = (media, startTime) => { | |||
this.props.onOpenVideo(media, startTime); | |||
handleOpenVideo = (media, options) => { | |||
this.props.onOpenVideo(media, options); | |||
} | |||
handleExpandedToggle = () => { | |||
@@ -129,8 +129,8 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ | |||
dispatch(openModal('MEDIA', { media, index })); | |||
}, | |||
onOpenVideo (media, time) { | |||
dispatch(openModal('VIDEO', { media, time })); | |||
onOpenVideo (media, options) { | |||
dispatch(openModal('VIDEO', { media, options })); | |||
}, | |||
onBlock (status) { | |||
@@ -277,8 +277,8 @@ class Status extends ImmutablePureComponent { | |||
this.props.dispatch(openModal('MEDIA', { media, index })); | |||
} | |||
handleOpenVideo = (media, time) => { | |||
this.props.dispatch(openModal('VIDEO', { media, time })); | |||
handleOpenVideo = (media, options) => { | |||
this.props.dispatch(openModal('VIDEO', { media, options })); | |||
} | |||
handleHotkeyOpenMedia = e => { | |||
@@ -290,7 +290,7 @@ class Status extends ImmutablePureComponent { | |||
if (status.getIn(['media_attachments', 0, 'type']) === 'audio') { | |||
// TODO: toggle play/paused? | |||
} 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 { | |||
this.handleOpenMedia(status.get('media_attachments'), 0); | |||
} | |||
@@ -14,7 +14,11 @@ export default class VideoModal extends ImmutablePureComponent { | |||
static propTypes = { | |||
media: ImmutablePropTypes.map.isRequired, | |||
status: ImmutablePropTypes.map, | |||
time: PropTypes.number, | |||
options: PropTypes.shape({ | |||
startTime: PropTypes.number, | |||
autoPlay: PropTypes.bool, | |||
defaultVolume: PropTypes.number, | |||
}), | |||
onClose: PropTypes.func.isRequired, | |||
}; | |||
@@ -52,7 +56,8 @@ export default class VideoModal extends ImmutablePureComponent { | |||
} | |||
render () { | |||
const { media, status, time, onClose } = this.props; | |||
const { media, status, onClose } = this.props; | |||
const options = this.props.options || {}; | |||
return ( | |||
<div className='modal-root__modal video-modal'> | |||
@@ -61,7 +66,9 @@ export default class VideoModal extends ImmutablePureComponent { | |||
preview={media.get('preview_url')} | |||
blurhash={media.get('blurhash')} | |||
src={media.get('url')} | |||
startTime={time} | |||
startTime={options.startTime} | |||
autoPlay={options.autoPlay} | |||
defaultVolume={options.defaultVolume} | |||
onCloseVideo={onClose} | |||
detailed | |||
alt={media.get('description')} | |||
@@ -109,6 +109,8 @@ class Video extends React.PureComponent { | |||
intl: PropTypes.object.isRequired, | |||
blurhash: PropTypes.string, | |||
link: PropTypes.node, | |||
autoPlay: PropTypes.bool, | |||
defaultVolume: PropTypes.number, | |||
}; | |||
state = { | |||
@@ -367,6 +369,13 @@ class Video extends React.PureComponent { | |||
handleLoadedData = () => { | |||
if (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(); | |||
} | |||
} | |||
@@ -393,8 +402,14 @@ class Video extends React.PureComponent { | |||
height, | |||
}); | |||
const options = { | |||
startTime: this.video.currentTime, | |||
autoPlay: !this.state.paused, | |||
defaultVolume: this.state.volume, | |||
}; | |||
this.video.pause(); | |||
this.props.onOpenVideo(media, this.video.currentTime); | |||
this.props.onOpenVideo(media, options); | |||
} | |||
handleCloseVideo = () => { | |||
@@ -138,7 +138,7 @@ const resizeImage = (img, type = 'image/png') => new Promise((resolve, 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') { | |||
resolve(inputFile); | |||
return; | |||
@@ -153,5 +153,5 @@ export default inputFile => new Promise((resolve, reject) => { | |||
resizeImage(img, inputFile.type) | |||
.then(resolve) | |||
.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 { | |||
&__list { | |||
width: 100%; | |||
@@ -27,7 +27,7 @@ class Relay < ApplicationRecord | |||
payload = Oj.dump(follow_activity(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) | |||
end | |||
@@ -36,7 +36,7 @@ class Relay < ApplicationRecord | |||
payload = Oj.dump(unfollow_activity(activity_id)) | |||
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) | |||
end | |||
@@ -163,7 +163,7 @@ | |||
"tesseract.js": "^2.0.0-alpha.16", | |||
"throng": "^4.0.0", | |||
"tiny-queue": "^0.2.1", | |||
"uuid": "^7.0.2", | |||
"uuid": "^7.0.3", | |||
"wavesurfer.js": "^3.3.1", | |||
"webpack": "^4.42.1", | |||
"webpack-assets-manifest": "^3.1.1", | |||
@@ -5065,12 +5065,12 @@ globby@^7.1.1: | |||
slash "^1.0.0" | |||
globule@^1.0.0: | |||
version "1.2.1" | |||
resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d" | |||
integrity sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ== | |||
version "1.3.1" | |||
resolved "https://registry.yarnpkg.com/globule/-/globule-1.3.1.tgz#90a25338f22b7fbeb527cee63c629aea754d33b9" | |||
integrity sha512-OVyWOHgw29yosRHCHo7NncwR1hW5ew0W/UrvtwvjefVJeQ26q4/8r8FmPsSF1hJ93IgWkyv16pCTz6WblMzm/g== | |||
dependencies: | |||
glob "~7.1.1" | |||
lodash "~4.17.10" | |||
lodash "~4.17.12" | |||
minimatch "~3.0.2" | |||
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" | |||
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" | |||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" | |||
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== | |||
@@ -10023,16 +10023,11 @@ side-channel@^1.0.2: | |||
es-abstract "^1.17.0-next.1" | |||
object-inspect "^1.7.0" | |||
signal-exit@^3.0.0: | |||
signal-exit@^3.0.0, signal-exit@^3.0.2: | |||
version "3.0.3" | |||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" | |||
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: | |||
version "0.2.2" | |||
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" | |||
sisteransi@^1.0.0: | |||
version "1.0.0" | |||
resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.0.tgz#77d9622ff909080f1c19e5f4a1df0c1b0a27b88c" | |||
integrity sha512-N+z4pHB4AmUv0SjveWRd6q1Nj5w62m5jodv+GD8lvmbY/83T/rpbJGZOnK5T149OldDj4Db07BSv9xY4K6NTPQ== | |||
version "1.0.5" | |||
resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" | |||
integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== | |||
slash@^1.0.0: | |||
version "1.0.0" | |||
@@ -10366,9 +10361,9 @@ stream-http@^2.7.2: | |||
xtend "^4.0.0" | |||
stream-shift@^1.0.0: | |||
version "1.0.0" | |||
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" | |||
integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= | |||
version "1.0.1" | |||
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" | |||
integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== | |||
strict-uri-encode@^1.0.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" | |||
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== | |||
uuid@^7.0.2: | |||
version "7.0.2" | |||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.2.tgz#7ff5c203467e91f5e0d85cfcbaaf7d2ebbca9be6" | |||
integrity sha512-vy9V/+pKG+5ZTYKf+VcphF5Oc6EFiu3W8Nv3P3zIh0EqVI80ZxOzuPfe9EHjkFNvf8+xuTHVeei4Drydlx4zjw== | |||
uuid@^7.0.3: | |||
version "7.0.3" | |||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" | |||
integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== | |||
v8-compile-cache@2.0.3, v8-compile-cache@^2.0.3: | |||
version "2.0.3" | |||