[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:
Eugen Rochko 2020-06-29 13:56:55 +02:00 committed by ThibG
parent 8999eea707
commit 9b3677d509
3 changed files with 33 additions and 15 deletions

View file

@ -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}

View file

@ -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,
}); });

View file

@ -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}
/> />
); );