From 9b5f073cb31e4fe45944a5b535304ee7fdf57a13 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 26 Sep 2024 14:31:32 +0200 Subject: [PATCH] [Glitch] Change design of media tab on profiles in web UI Port 89df27a06c69818d38621c1147c6724d76beefde to glitch-soc Signed-off-by: Claire --- .../glitch/components/media_gallery.jsx | 13 +- .../flavours/glitch/components/status.jsx | 42 ++-- .../account_gallery/components/media_item.jsx | 158 -------------- .../account_gallery/components/media_item.tsx | 200 ++++++++++++++++++ .../glitch/features/account_gallery/index.jsx | 2 +- .../status/components/detailed_status.tsx | 39 ++-- .../flavours/glitch/models/status.ts | 2 + .../flavours/glitch/styles/components.scss | 99 +++++---- .../flavours/glitch/styles/variables.scss | 2 + 9 files changed, 320 insertions(+), 237 deletions(-) delete mode 100644 app/javascript/flavours/glitch/features/account_gallery/components/media_item.jsx create mode 100644 app/javascript/flavours/glitch/features/account_gallery/components/media_item.tsx diff --git a/app/javascript/flavours/glitch/components/media_gallery.jsx b/app/javascript/flavours/glitch/components/media_gallery.jsx index 5be5fb4c58..1e40a26777 100644 --- a/app/javascript/flavours/glitch/components/media_gallery.jsx +++ b/app/javascript/flavours/glitch/components/media_gallery.jsx @@ -11,6 +11,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import { debounce } from 'lodash'; import { Blurhash } from 'flavours/glitch/components/blurhash'; +import { formatTime } from 'flavours/glitch/features/video'; import { autoPlayGif, displayMedia, useBlurhash } from '../initial_state'; @@ -58,7 +59,7 @@ class Item extends PureComponent { hoverToPlay () { const { attachment } = this.props; - return !this.getAutoPlay() && attachment.get('type') === 'gifv'; + return !this.getAutoPlay() && ['gifv', 'video'].includes(attachment.get('type')); } handleClick = (e) => { @@ -152,10 +153,15 @@ class Item extends PureComponent { /> ); - } else if (attachment.get('type') === 'gifv') { + } else if (['gifv', 'video'].includes(attachment.get('type'))) { const autoPlay = this.getAutoPlay(); + const duration = attachment.getIn(['meta', 'original', 'duration']); - badges.push(GIF); + if (attachment.get('type') === 'gifv') { + badges.push(GIF); + } else { + badges.push({formatTime(Math.floor(duration))}); + } thumbnail = (
@@ -169,6 +175,7 @@ class Item extends PureComponent { onClick={this.handleClick} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} + onLoadedData={this.handleImageLoad} autoPlay={autoPlay} playsInline loop diff --git a/app/javascript/flavours/glitch/components/status.jsx b/app/javascript/flavours/glitch/components/status.jsx index a037895b4e..493ef4f68a 100644 --- a/app/javascript/flavours/glitch/components/status.jsx +++ b/app/javascript/flavours/glitch/components/status.jsx @@ -648,6 +648,27 @@ class Status extends ImmutablePureComponent { media={status.get('media_attachments')} />, ); + } else if (['image', 'gifv'].includes(status.getIn(['media_attachments', 0, 'type'])) || status.get('media_attachments').size > 1) { + media.push( + + {Component => ( + , + ); + mediaIcons.push('picture-o'); } else if (attachments.getIn([0, 'type']) === 'audio') { const attachment = status.getIn(['media_attachments', 0]); const description = attachment.getIn(['translation', 'description']) || attachment.get('description'); @@ -703,27 +724,6 @@ class Status extends ImmutablePureComponent { , ); mediaIcons.push('video-camera'); - } else { // Media type is 'image' or 'gifv' - media.push( - - {Component => ( - , - ); - mediaIcons.push('picture-o'); } if (!status.get('sensitive') && !(status.get('spoiler_text').length > 0) && settings.getIn(['collapsed', 'backgrounds', 'preview_images'])) { diff --git a/app/javascript/flavours/glitch/features/account_gallery/components/media_item.jsx b/app/javascript/flavours/glitch/features/account_gallery/components/media_item.jsx deleted file mode 100644 index c709e58db1..0000000000 --- a/app/javascript/flavours/glitch/features/account_gallery/components/media_item.jsx +++ /dev/null @@ -1,158 +0,0 @@ -import PropTypes from 'prop-types'; - -import classNames from 'classnames'; - -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; - -import AudiotrackIcon from '@/material-icons/400-24px/music_note.svg?react'; -import PlayArrowIcon from '@/material-icons/400-24px/play_arrow.svg?react'; -import VisibilityOffIcon from '@/material-icons/400-24px/visibility_off.svg?react'; -import { Blurhash } from 'flavours/glitch/components/blurhash'; -import { Icon } from 'flavours/glitch/components/icon'; -import { autoPlayGif, displayMedia, useBlurhash } from 'flavours/glitch/initial_state'; - -export default class MediaItem extends ImmutablePureComponent { - - static propTypes = { - attachment: ImmutablePropTypes.map.isRequired, - displayWidth: PropTypes.number.isRequired, - onOpenMedia: PropTypes.func.isRequired, - }; - - state = { - visible: displayMedia !== 'hide_all' && !this.props.attachment.getIn(['status', 'sensitive']) || displayMedia === 'show_all', - loaded: false, - }; - - handleImageLoad = () => { - this.setState({ loaded: true }); - }; - - handleMouseEnter = e => { - if (this.hoverToPlay()) { - e.target.play(); - } - }; - - handleMouseLeave = e => { - if (this.hoverToPlay()) { - e.target.pause(); - e.target.currentTime = 0; - } - }; - - hoverToPlay () { - return !autoPlayGif && ['gifv', 'video'].indexOf(this.props.attachment.get('type')) !== -1; - } - - handleClick = e => { - if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { - e.preventDefault(); - - if (this.state.visible) { - this.props.onOpenMedia(this.props.attachment); - } else { - this.setState({ visible: true }); - } - } - }; - - render () { - const { attachment, displayWidth } = this.props; - const { visible, loaded } = this.state; - - const width = `${Math.floor((displayWidth - 4) / 3) - 4}px`; - const height = width; - const status = attachment.get('status'); - const title = status.get('spoiler_text') || attachment.get('description'); - - let thumbnail, label, icon, content; - - if (!visible) { - icon = ( - - - - ); - } else { - if (['audio', 'video'].includes(attachment.get('type'))) { - content = ( - {attachment.get('description')} - ); - - if (attachment.get('type') === 'audio') { - label = ; - } else { - label = ; - } - } else if (attachment.get('type') === 'image') { - const focusX = attachment.getIn(['meta', 'focus', 'x']) || 0; - const focusY = attachment.getIn(['meta', 'focus', 'y']) || 0; - const x = ((focusX / 2) + .5) * 100; - const y = ((focusY / -2) + .5) * 100; - - content = ( - {attachment.get('description')} - ); - } else if (attachment.get('type') === 'gifv') { - content = ( -