Change design of audio player in web UI (#34520)
This commit is contained in:
parent
24c25ec4f5
commit
b4394ec129
26 changed files with 1476 additions and 1088 deletions
|
@ -1,74 +0,0 @@
|
|||
import PropTypes from 'prop-types';
|
||||
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { getAverageFromBlurhash } from 'mastodon/blurhash';
|
||||
import Audio from 'mastodon/features/audio';
|
||||
import Footer from 'mastodon/features/picture_in_picture/components/footer';
|
||||
|
||||
const mapStateToProps = (state, { statusId }) => ({
|
||||
status: state.getIn(['statuses', statusId]),
|
||||
accountStaticAvatar: state.getIn(['accounts', state.getIn(['statuses', statusId, 'account']), 'avatar_static']),
|
||||
});
|
||||
|
||||
class AudioModal extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
media: ImmutablePropTypes.map.isRequired,
|
||||
statusId: PropTypes.string.isRequired,
|
||||
status: ImmutablePropTypes.map.isRequired,
|
||||
accountStaticAvatar: PropTypes.string.isRequired,
|
||||
options: PropTypes.shape({
|
||||
autoPlay: PropTypes.bool,
|
||||
}),
|
||||
onClose: PropTypes.func.isRequired,
|
||||
onChangeBackgroundColor: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
componentDidMount () {
|
||||
const { media, onChangeBackgroundColor } = this.props;
|
||||
|
||||
const backgroundColor = getAverageFromBlurhash(media.get('blurhash'));
|
||||
|
||||
onChangeBackgroundColor(backgroundColor || { r: 255, g: 255, b: 255 });
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
this.props.onChangeBackgroundColor(null);
|
||||
}
|
||||
|
||||
render () {
|
||||
const { media, status, accountStaticAvatar, onClose } = this.props;
|
||||
const options = this.props.options || {};
|
||||
const language = status.getIn(['translation', 'language']) || status.get('language');
|
||||
const description = media.getIn(['translation', 'description']) || media.get('description');
|
||||
|
||||
return (
|
||||
<div className='modal-root__modal audio-modal'>
|
||||
<div className='audio-modal__container'>
|
||||
<Audio
|
||||
src={media.get('url')}
|
||||
alt={description}
|
||||
lang={language}
|
||||
duration={media.getIn(['meta', 'original', 'duration'], 0)}
|
||||
height={150}
|
||||
poster={media.get('preview_url') || accountStaticAvatar}
|
||||
backgroundColor={media.getIn(['meta', 'colors', 'background'])}
|
||||
foregroundColor={media.getIn(['meta', 'colors', 'foreground'])}
|
||||
accentColor={media.getIn(['meta', 'colors', 'accent'])}
|
||||
autoPlay={options.autoPlay}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='media-modal__overlay'>
|
||||
{status && <Footer statusId={status.get('id')} withOpenButton onClose={onClose} />}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, null, null, { forwardRef: true })(AudioModal);
|
|
@ -0,0 +1,78 @@
|
|||
import { useEffect } from 'react';
|
||||
|
||||
import { getAverageFromBlurhash } from 'mastodon/blurhash';
|
||||
import type { RGB } from 'mastodon/blurhash';
|
||||
import { Audio } from 'mastodon/features/audio';
|
||||
import { Footer } from 'mastodon/features/picture_in_picture/components/footer';
|
||||
import type { MediaAttachment } from 'mastodon/models/media_attachment';
|
||||
import { useAppSelector } from 'mastodon/store';
|
||||
|
||||
const AudioModal: React.FC<{
|
||||
media: MediaAttachment;
|
||||
statusId: string;
|
||||
options: {
|
||||
autoPlay: boolean;
|
||||
};
|
||||
onClose: () => void;
|
||||
onChangeBackgroundColor: (color: RGB | null) => void;
|
||||
}> = ({ media, statusId, options, onClose, onChangeBackgroundColor }) => {
|
||||
const status = useAppSelector((state) => state.statuses.get(statusId));
|
||||
const accountId = status?.get('account') as string | undefined;
|
||||
const accountStaticAvatar = useAppSelector((state) =>
|
||||
accountId ? state.accounts.get(accountId)?.avatar_static : undefined,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const backgroundColor = getAverageFromBlurhash(
|
||||
media.get('blurhash') as string | null,
|
||||
);
|
||||
|
||||
onChangeBackgroundColor(backgroundColor ?? { r: 255, g: 255, b: 255 });
|
||||
|
||||
return () => {
|
||||
onChangeBackgroundColor(null);
|
||||
};
|
||||
}, [media, onChangeBackgroundColor]);
|
||||
|
||||
const language = (status?.getIn(['translation', 'language']) ??
|
||||
status?.get('language')) as string;
|
||||
const description = (media.getIn(['translation', 'description']) ??
|
||||
media.get('description')) as string;
|
||||
|
||||
return (
|
||||
<div className='modal-root__modal audio-modal'>
|
||||
<div className='audio-modal__container'>
|
||||
<Audio
|
||||
src={media.get('url') as string}
|
||||
alt={description}
|
||||
lang={language}
|
||||
poster={
|
||||
(media.get('preview_url') as string | null) ?? accountStaticAvatar
|
||||
}
|
||||
duration={media.getIn(['meta', 'original', 'duration'], 0) as number}
|
||||
backgroundColor={
|
||||
media.getIn(['meta', 'colors', 'background']) as string
|
||||
}
|
||||
foregroundColor={
|
||||
media.getIn(['meta', 'colors', 'foreground']) as string
|
||||
}
|
||||
accentColor={media.getIn(['meta', 'colors', 'accent']) as string}
|
||||
startPlaying={options.autoPlay}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='media-modal__overlay'>
|
||||
{status && (
|
||||
<Footer
|
||||
statusId={status.get('id') as string}
|
||||
withOpenButton
|
||||
onClose={onClose}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default AudioModal;
|
|
@ -18,7 +18,7 @@ import { getAverageFromBlurhash } from 'mastodon/blurhash';
|
|||
import { GIFV } from 'mastodon/components/gifv';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
import { IconButton } from 'mastodon/components/icon_button';
|
||||
import Footer from 'mastodon/features/picture_in_picture/components/footer';
|
||||
import { Footer } from 'mastodon/features/picture_in_picture/components/footer';
|
||||
import { Video } from 'mastodon/features/video';
|
||||
import { disableSwiping } from 'mastodon/initial_state';
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
|
|||
import { connect } from 'react-redux';
|
||||
|
||||
import { getAverageFromBlurhash } from 'mastodon/blurhash';
|
||||
import Footer from 'mastodon/features/picture_in_picture/components/footer';
|
||||
import { Footer } from 'mastodon/features/picture_in_picture/components/footer';
|
||||
import { Video } from 'mastodon/features/video';
|
||||
|
||||
const mapStateToProps = (state, { statusId }) => ({
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue