mirror of
https://github.com/mastodon/mastodon.git
synced 2024-12-12 14:16:12 +01:00
[Glitch] Add customizable thumbnails for audio and video attachments
Port 64aac30733
to glitch-soc
Signed-off-by: Thibaut Girka <thib@sitedethib.com>
This commit is contained in:
parent
8999eea707
commit
9b3677d509
@ -591,7 +591,8 @@ class Status extends ImmutablePureComponent {
|
|||||||
<Component
|
<Component
|
||||||
src={attachment.get('url')}
|
src={attachment.get('url')}
|
||||||
alt={attachment.get('description')}
|
alt={attachment.get('description')}
|
||||||
poster={status.getIn(['account', 'avatar_static'])}
|
poster={attachment.get('preview_url') || status.getIn(['account', 'avatar_static'])}
|
||||||
|
blurhash={attachment.get('blurhash')}
|
||||||
duration={attachment.getIn(['meta', 'original', 'duration'], 0)}
|
duration={attachment.getIn(['meta', 'original', 'duration'], 0)}
|
||||||
width={this.props.cachedMediaWidth}
|
width={this.props.cachedMediaWidth}
|
||||||
height={110}
|
height={110}
|
||||||
|
@ -157,6 +157,7 @@ class Audio extends React.PureComponent {
|
|||||||
fullscreen: PropTypes.bool,
|
fullscreen: PropTypes.bool,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
cacheWidth: PropTypes.func,
|
cacheWidth: PropTypes.func,
|
||||||
|
blurhash: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
@ -221,32 +222,42 @@ class Audio extends React.PureComponent {
|
|||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
window.addEventListener('resize', this.handleResize, { passive: true });
|
window.addEventListener('resize', this.handleResize, { passive: true });
|
||||||
|
|
||||||
const img = new Image();
|
if (!this.props.blurhash) {
|
||||||
img.crossOrigin = 'anonymous';
|
const img = new Image();
|
||||||
img.onload = () => this.handlePosterLoad(img);
|
img.crossOrigin = 'anonymous';
|
||||||
img.src = this.props.poster;
|
img.onload = () => this.handlePosterLoad(img);
|
||||||
|
img.src = this.props.poster;
|
||||||
|
} else {
|
||||||
|
this._setColorScheme();
|
||||||
|
this._decodeBlurhash();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate (prevProps, prevState) {
|
componentDidUpdate (prevProps, prevState) {
|
||||||
if (prevProps.poster !== this.props.poster) {
|
if (prevProps.poster !== this.props.poster && !this.props.blurhash) {
|
||||||
const img = new Image();
|
const img = new Image();
|
||||||
img.crossOrigin = 'anonymous';
|
img.crossOrigin = 'anonymous';
|
||||||
img.onload = () => this.handlePosterLoad(img);
|
img.onload = () => this.handlePosterLoad(img);
|
||||||
img.src = this.props.poster;
|
img.src = this.props.poster;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prevState.blurhash !== this.state.blurhash) {
|
if (prevState.blurhash !== this.state.blurhash || prevProps.blurhash !== this.props.blurhash) {
|
||||||
const context = this.blurhashCanvas.getContext('2d');
|
this._setColorScheme();
|
||||||
const pixels = decode(this.state.blurhash, 32, 32);
|
this._decodeBlurhash();
|
||||||
const outputImageData = new ImageData(pixels, 32, 32);
|
|
||||||
|
|
||||||
context.putImageData(outputImageData, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this._clear();
|
this._clear();
|
||||||
this._draw();
|
this._draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_decodeBlurhash () {
|
||||||
|
const context = this.blurhashCanvas.getContext('2d');
|
||||||
|
const pixels = decode(this.props.blurhash || this.state.blurhash, 32, 32);
|
||||||
|
const outputImageData = new ImageData(pixels, 32, 32);
|
||||||
|
|
||||||
|
context.putImageData(outputImageData, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
componentWillUnmount () {
|
componentWillUnmount () {
|
||||||
window.removeEventListener('resize', this.handleResize);
|
window.removeEventListener('resize', this.handleResize);
|
||||||
}
|
}
|
||||||
@ -400,7 +411,7 @@ class Audio extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handlePosterLoad = image => {
|
handlePosterLoad = image => {
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
const context = canvas.getContext('2d');
|
const context = canvas.getContext('2d');
|
||||||
|
|
||||||
canvas.width = image.width;
|
canvas.width = image.width;
|
||||||
@ -410,10 +421,15 @@ class Audio extends React.PureComponent {
|
|||||||
|
|
||||||
const inputImageData = context.getImageData(0, 0, image.width, image.height);
|
const inputImageData = context.getImageData(0, 0, image.width, image.height);
|
||||||
const blurhash = encode(inputImageData.data, image.width, image.height, 4, 4);
|
const blurhash = encode(inputImageData.data, image.width, image.height, 4, 4);
|
||||||
|
|
||||||
|
this.setState({ blurhash });
|
||||||
|
}
|
||||||
|
|
||||||
|
_setColorScheme () {
|
||||||
|
const blurhash = this.props.blurhash || this.state.blurhash;
|
||||||
const averageColor = decodeRGB(decode83(blurhash.slice(2, 6)));
|
const averageColor = decodeRGB(decode83(blurhash.slice(2, 6)));
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
blurhash,
|
|
||||||
color: adjustColor(averageColor),
|
color: adjustColor(averageColor),
|
||||||
darkText: luma(averageColor) >= 165,
|
darkText: luma(averageColor) >= 165,
|
||||||
});
|
});
|
||||||
|
@ -142,7 +142,8 @@ export default class DetailedStatus extends ImmutablePureComponent {
|
|||||||
src={attachment.get('url')}
|
src={attachment.get('url')}
|
||||||
alt={attachment.get('description')}
|
alt={attachment.get('description')}
|
||||||
duration={attachment.getIn(['meta', 'original', 'duration'], 0)}
|
duration={attachment.getIn(['meta', 'original', 'duration'], 0)}
|
||||||
poster={status.getIn(['account', 'avatar_static'])}
|
poster={attachment.get('preview_url') || status.getIn(['account', 'avatar_static'])}
|
||||||
|
blurhash={attachment.get('blurhash')}
|
||||||
height={150}
|
height={150}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user