From 8f950e540b83e13748c0df9bc30afbb06ef26f3e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 28 Sep 2020 13:29:43 +0200 Subject: [Glitch] Add pop-out player for audio/video in web UI port d88a79b4566869ede24958fbff946e357bbb3cb9 to glitch-soc Signed-off-by: Thibaut Girka --- .../flavours/glitch/components/animated_number.js | 17 +++++- .../flavours/glitch/components/icon_button.js | 11 +++- .../components/picture_in_picture_placeholder.js | 69 ++++++++++++++++++++++ .../flavours/glitch/components/status.js | 16 +++++ .../glitch/components/status_action_bar.js | 22 +++---- 5 files changed, 117 insertions(+), 18 deletions(-) create mode 100644 app/javascript/flavours/glitch/components/picture_in_picture_placeholder.js (limited to 'app/javascript/flavours/glitch/components') diff --git a/app/javascript/flavours/glitch/components/animated_number.js b/app/javascript/flavours/glitch/components/animated_number.js index e3235e368..3cc5173dd 100644 --- a/app/javascript/flavours/glitch/components/animated_number.js +++ b/app/javascript/flavours/glitch/components/animated_number.js @@ -5,10 +5,21 @@ import TransitionMotion from 'react-motion/lib/TransitionMotion'; import spring from 'react-motion/lib/spring'; import { reduceMotion } from 'flavours/glitch/util/initial_state'; +const obfuscatedCount = count => { + if (count < 0) { + return 0; + } else if (count <= 1) { + return count; + } else { + return '1+'; + } +}; + export default class AnimatedNumber extends React.PureComponent { static propTypes = { value: PropTypes.number.isRequired, + obfuscate: PropTypes.bool, }; state = { @@ -36,11 +47,11 @@ export default class AnimatedNumber extends React.PureComponent { } render () { - const { value } = this.props; + const { value, obfuscate } = this.props; const { direction } = this.state; if (reduceMotion) { - return ; + return obfuscate ? obfuscatedCount(value) : ; } const styles = [{ @@ -54,7 +65,7 @@ export default class AnimatedNumber extends React.PureComponent { {items => ( {items.map(({ key, data, style }) => ( - 0 ? 'absolute' : 'static', transform: `translateY(${style.y * 100}%)` }}> + 0 ? 'absolute' : 'static', transform: `translateY(${style.y * 100}%)` }}>{obfuscate ? obfuscatedCount(data) : } ))} )} diff --git a/app/javascript/flavours/glitch/components/icon_button.js b/app/javascript/flavours/glitch/components/icon_button.js index e134d0a39..51540d17d 100644 --- a/app/javascript/flavours/glitch/components/icon_button.js +++ b/app/javascript/flavours/glitch/components/icon_button.js @@ -4,6 +4,7 @@ import spring from 'react-motion/lib/spring'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import Icon from 'flavours/glitch/components/icon'; +import AnimatedNumber from 'flavours/glitch/components/animated_number'; export default class IconButton extends React.PureComponent { @@ -27,6 +28,8 @@ export default class IconButton extends React.PureComponent { overlay: PropTypes.bool, tabIndex: PropTypes.string, label: PropTypes.string, + counter: PropTypes.number, + obfuscateCount: PropTypes.bool, }; static defaultProps = { @@ -104,6 +107,8 @@ export default class IconButton extends React.PureComponent { pressed, tabIndex, title, + counter, + obfuscateCount, } = this.props; const { @@ -120,6 +125,10 @@ export default class IconButton extends React.PureComponent { overlayed: overlay, }); + if (typeof counter !== 'undefined') { + style.width = 'auto'; + } + return ( ); diff --git a/app/javascript/flavours/glitch/components/picture_in_picture_placeholder.js b/app/javascript/flavours/glitch/components/picture_in_picture_placeholder.js new file mode 100644 index 000000000..01dce0a38 --- /dev/null +++ b/app/javascript/flavours/glitch/components/picture_in_picture_placeholder.js @@ -0,0 +1,69 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import Icon from 'flavours/glitch/components/icon'; +import { removePictureInPicture } from 'flavours/glitch/actions/picture_in_picture'; +import { connect } from 'react-redux'; +import { debounce } from 'lodash'; +import { FormattedMessage } from 'react-intl'; + +export default @connect() +class PictureInPicturePlaceholder extends React.PureComponent { + + static propTypes = { + width: PropTypes.number, + dispatch: PropTypes.func.isRequired, + }; + + state = { + width: this.props.width, + height: this.props.width && (this.props.width / (16/9)), + }; + + handleClick = () => { + const { dispatch } = this.props; + dispatch(removePictureInPicture()); + } + + setRef = c => { + this.node = c; + + if (this.node) { + this._setDimensions(); + } + } + + _setDimensions () { + const width = this.node.offsetWidth; + const height = width / (16/9); + + this.setState({ width, height }); + } + + componentDidMount () { + window.addEventListener('resize', this.handleResize, { passive: true }); + } + + componentWillUnmount () { + window.removeEventListener('resize', this.handleResize); + } + + handleResize = debounce(() => { + if (this.node) { + this._setDimensions(); + } + }, 250, { + trailing: true, + }); + + render () { + const { height } = this.state; + + return ( +
+ + +
+ ); + } + +} diff --git a/app/javascript/flavours/glitch/components/status.js b/app/javascript/flavours/glitch/components/status.js index fc7940e5a..1b7dce4c4 100644 --- a/app/javascript/flavours/glitch/components/status.js +++ b/app/javascript/flavours/glitch/components/status.js @@ -17,6 +17,7 @@ import classNames from 'classnames'; import { autoUnfoldCW } from 'flavours/glitch/util/content_warning'; import PollContainer from 'flavours/glitch/containers/poll_container'; import { displayMedia } from 'flavours/glitch/util/initial_state'; +import PictureInPicturePlaceholder from 'flavours/glitch/components/picture_in_picture_placeholder'; // We use the component (and not the container) since we do not want // to use the progress bar to show download progress @@ -97,6 +98,8 @@ class Status extends ImmutablePureComponent { cachedMediaWidth: PropTypes.number, onClick: PropTypes.func, scrollKey: PropTypes.string, + deployPictureInPicture: PropTypes.func, + usingPiP: PropTypes.bool, }; state = { @@ -123,6 +126,7 @@ class Status extends ImmutablePureComponent { 'hidden', 'expanded', 'unread', + 'usingPiP', ] updateOnStates = [ @@ -394,6 +398,12 @@ class Status extends ImmutablePureComponent { } } + handleDeployPictureInPicture = (type, mediaProps) => { + const { deployPictureInPicture, status } = this.props; + + deployPictureInPicture(status, type, mediaProps); + } + handleHotkeyReply = e => { e.preventDefault(); this.props.onReply(this.props.status, this.context.router.history); @@ -496,6 +506,7 @@ class Status extends ImmutablePureComponent { hidden, unread, featured, + usingPiP, ...other } = this.props; const { isExpanded, isCollapsed, forceFilter } = this.state; @@ -576,6 +587,9 @@ class Status extends ImmutablePureComponent { if (status.get('poll')) { media = ; mediaIcon = 'tasks'; + } else if (usingPiP) { + media = ; + mediaIcon = 'video-camera'; } else if (attachments.size > 0) { if (muted || attachments.some(item => item.get('type') === 'unknown')) { media = ( @@ -601,6 +615,7 @@ class Status extends ImmutablePureComponent { width={this.props.cachedMediaWidth} height={110} cacheWidth={this.props.cacheMediaWidth} + deployPictureInPicture={this.handleDeployPictureInPicture} /> )} @@ -624,6 +639,7 @@ class Status extends ImmutablePureComponent { onOpenVideo={this.handleOpenVideo} width={this.props.cachedMediaWidth} cacheWidth={this.props.cacheMediaWidth} + deployPictureInPicture={this.handleDeployPictureInPicture} visible={this.state.showMedia} onToggleVisibility={this.handleToggleMediaVisibility} />)} diff --git a/app/javascript/flavours/glitch/components/status_action_bar.js b/app/javascript/flavours/glitch/components/status_action_bar.js index cfb03c21b..2ccb02c62 100644 --- a/app/javascript/flavours/glitch/components/status_action_bar.js +++ b/app/javascript/flavours/glitch/components/status_action_bar.js @@ -40,16 +40,6 @@ const messages = defineMessages({ hide: { id: 'status.hide', defaultMessage: 'Hide toot' }, }); -const obfuscatedCount = count => { - if (count < 0) { - return 0; - } else if (count <= 1) { - return count; - } else { - return '1+'; - } -}; - export default @injectIntl class StatusActionBar extends ImmutablePureComponent { @@ -284,10 +274,14 @@ class StatusActionBar extends ImmutablePureComponent { ); if (showReplyCount) { replyButton = ( -
- {replyButton} - {obfuscatedCount(status.get('replies_count'))} -
+ ); } -- cgit From 47edac871c7e20ddc5bc106e3976891873b4f346 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 4 Oct 2020 15:02:36 +0200 Subject: [Glitch] Fix regressions in icon buttons in web UI Port a549415868fe23e0afaf258c17afafac117d0163 to glitch-soc Signed-off-by: Thibaut Girka --- app/javascript/flavours/glitch/components/icon_button.js | 1 + app/javascript/flavours/glitch/styles/components/index.scss | 10 ++++++++-- app/javascript/flavours/glitch/styles/components/status.scss | 4 ++++ 3 files changed, 13 insertions(+), 2 deletions(-) (limited to 'app/javascript/flavours/glitch/components') diff --git a/app/javascript/flavours/glitch/components/icon_button.js b/app/javascript/flavours/glitch/components/icon_button.js index 51540d17d..58d3568dd 100644 --- a/app/javascript/flavours/glitch/components/icon_button.js +++ b/app/javascript/flavours/glitch/components/icon_button.js @@ -123,6 +123,7 @@ export default class IconButton extends React.PureComponent { activate, deactivate, overlayed: overlay, + 'icon-button--with-counter': typeof counter !== 'undefined', }); if (typeof counter !== 'undefined') { diff --git a/app/javascript/flavours/glitch/styles/components/index.scss b/app/javascript/flavours/glitch/styles/components/index.scss index 337005a59..0614278e2 100644 --- a/app/javascript/flavours/glitch/styles/components/index.scss +++ b/app/javascript/flavours/glitch/styles/components/index.scss @@ -144,8 +144,7 @@ } .icon-button { - display: inline-flex; - align-items: center; + display: inline-block; padding: 0; color: $action-button-color; border: 0; @@ -154,6 +153,7 @@ cursor: pointer; transition: all 100ms ease-in; transition-property: background-color, color; + text-decoration: none; &:hover, &:active, @@ -228,6 +228,12 @@ } } + &--with-counter { + display: inline-flex; + align-items: center; + width: auto !important; + } + &__counter { display: inline-block; width: 14px; diff --git a/app/javascript/flavours/glitch/styles/components/status.scss b/app/javascript/flavours/glitch/styles/components/status.scss index c589d935a..7ec377bad 100644 --- a/app/javascript/flavours/glitch/styles/components/status.scss +++ b/app/javascript/flavours/glitch/styles/components/status.scss @@ -568,6 +568,10 @@ .status__action-bar-button { margin-right: 18px; + + &.icon-button--with-counter { + margin-right: 14px; + } } .status__action-bar-dropdown { -- cgit