Show blurhash only after 150ms

Blurhash on every single room entrance was extremely annoying, to the
point where it wasn't really helpful, but distracting, even after
the animations was added.
This commit makes it so the blurhash is only shown after 150ms, and the
image will be animated as a quick fade-in if there's no blurhash.

Fixes https://github.com/vector-im/element-web/issues/18617
Fixes https://github.com/vector-im/element-web/issues/17879
This commit is contained in:
Dariusz Niemczyk 2021-08-19 07:48:44 +02:00
parent 90a6f251c7
commit 7adfbf6f98
No known key found for this signature in database
GPG key ID: 3E8DC619E3C59A05
2 changed files with 25 additions and 1 deletions

View file

@ -36,6 +36,10 @@ $timelineImageBorderRadius: 4px;
animation: mx--anim-pulse 1.75s infinite cubic-bezier(.4, 0, .6, 1);
border-radius: $timelineImageBorderRadius;
}
.mx_no-image-placeholder {
background-color: $primary-bg-color;
}
}
.mx_MImageBody_thumbnail_container {

View file

@ -47,6 +47,7 @@ interface IState {
};
hover: boolean;
showImage: boolean;
placeholder: 'no-image' | 'blurhash';
}
@replaceableComponent("views.messages.MImageBody")
@ -68,6 +69,7 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
loadedImageDimensions: null,
hover: false,
showImage: SettingsStore.getValue("showImages"),
placeholder: 'no-image',
};
}
@ -277,6 +279,17 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
this.downloadImage();
this.setState({ showImage: true });
} // else don't download anything because we don't want to display anything.
// Add a 150ms timer for blurhash to first appear.
if (this.media.isEncrypted) {
setTimeout(() => {
if (!this.state.imgLoaded || !this.state.imgError) {
this.setState({
placeholder: 'blurhash',
});
}
}, 150);
}
}
componentWillUnmount() {
@ -434,7 +447,14 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
// Overidden by MStickerBody
protected getPlaceholder(width: number, height: number): JSX.Element {
const blurhash = this.props.mxEvent.getContent().info[BLURHASH_FIELD];
if (blurhash) return <Blurhash className="mx_Blurhash" hash={blurhash} width={width} height={height} />;
if (blurhash) {
if (this.state.placeholder === 'no-image') {
return <div className="mx_no-image-placeholder" style={{ width: width, height: height }} />;
} else if (this.state.placeholder === 'blurhash') {
return <Blurhash className="mx_Blurhash" hash={blurhash} width={width} height={height} />;
}
}
return (
<InlineSpinner w={32} h={32} />
);