Don't let quote thumbnails get taller than the quote itself
This commit is contained in:
parent
ca669a2638
commit
932e44e3bf
3 changed files with 81 additions and 31 deletions
|
@ -1616,10 +1616,6 @@ $timer-icons: '55', '50', '45', '40', '35', '30', '25', '20', '15', '10', '05',
|
|||
|
||||
.module-quote {
|
||||
@include button-reset;
|
||||
|
||||
display: block;
|
||||
// To leave room for image thumbnail
|
||||
min-height: 54px;
|
||||
width: 100%;
|
||||
|
||||
position: relative;
|
||||
|
@ -1760,7 +1756,8 @@ $timer-icons: '55', '50', '45', '40', '35', '30', '25', '20', '15', '10', '05',
|
|||
padding-top: 7px;
|
||||
padding-bottom: 7px;
|
||||
|
||||
max-width: 100%;
|
||||
// To leave room for image thumbnail
|
||||
min-height: 54px;
|
||||
}
|
||||
|
||||
.module-quote__primary__author {
|
||||
|
@ -1899,16 +1896,11 @@ $timer-icons: '55', '50', '45', '40', '35', '30', '25', '20', '15', '10', '05',
|
|||
}
|
||||
|
||||
.module-quote__icon-container {
|
||||
flex: initial;
|
||||
min-width: 54px;
|
||||
width: 54px;
|
||||
background-size: cover;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
flex: auto auto 54px;
|
||||
position: relative;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.module-quote__icon-container__inner {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
// Copyright 2018-2020 Signal Messenger, LLC
|
||||
// Copyright 2018-2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import React, { useRef, useState, useEffect, ReactNode } from 'react';
|
||||
import { noop } from 'lodash';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import * as MIME from '../../types/MIME';
|
||||
|
@ -132,11 +133,7 @@ export class Quote extends React.Component<Props, State> {
|
|||
});
|
||||
};
|
||||
|
||||
public renderImage(
|
||||
url: string,
|
||||
i18n: LocalizerType,
|
||||
icon?: string
|
||||
): JSX.Element {
|
||||
public renderImage(url: string, icon?: string): JSX.Element {
|
||||
const iconElement = icon ? (
|
||||
<div className="module-quote__icon-container__inner">
|
||||
<div className="module-quote__icon-container__circle-background">
|
||||
|
@ -151,14 +148,9 @@ export class Quote extends React.Component<Props, State> {
|
|||
) : null;
|
||||
|
||||
return (
|
||||
<div className="module-quote__icon-container">
|
||||
<img
|
||||
src={url}
|
||||
alt={i18n('quoteThumbnailAlt')}
|
||||
onError={this.handleImageError}
|
||||
/>
|
||||
<ThumbnailImage src={url} onError={this.handleImageError}>
|
||||
{iconElement}
|
||||
</div>
|
||||
</ThumbnailImage>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -213,7 +205,7 @@ export class Quote extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
public renderIconContainer(): JSX.Element | null {
|
||||
const { attachment, i18n } = this.props;
|
||||
const { attachment } = this.props;
|
||||
const { imageBroken } = this.state;
|
||||
|
||||
if (!attachment) {
|
||||
|
@ -225,12 +217,12 @@ export class Quote extends React.Component<Props, State> {
|
|||
|
||||
if (GoogleChrome.isVideoTypeSupported(contentType)) {
|
||||
return objectUrl && !imageBroken
|
||||
? this.renderImage(objectUrl, i18n, 'play')
|
||||
? this.renderImage(objectUrl, 'play')
|
||||
: this.renderIcon('movie');
|
||||
}
|
||||
if (GoogleChrome.isImageTypeSupported(contentType)) {
|
||||
return objectUrl && !imageBroken
|
||||
? this.renderImage(objectUrl, i18n)
|
||||
? this.renderImage(objectUrl)
|
||||
: this.renderIcon('image');
|
||||
}
|
||||
if (MIME.isAudio(contentType)) {
|
||||
|
@ -441,3 +433,51 @@ export class Quote extends React.Component<Props, State> {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
function ThumbnailImage({
|
||||
src,
|
||||
onError,
|
||||
children,
|
||||
}: Readonly<{
|
||||
src: string;
|
||||
onError: () => void;
|
||||
children: ReactNode;
|
||||
}>): JSX.Element {
|
||||
const imageRef = useRef(new Image());
|
||||
const [loadedSrc, setLoadedSrc] = useState<null | string>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const image = new Image();
|
||||
image.onload = () => {
|
||||
setLoadedSrc(src);
|
||||
};
|
||||
image.src = src;
|
||||
imageRef.current = image;
|
||||
return () => {
|
||||
image.onload = noop;
|
||||
};
|
||||
}, [src]);
|
||||
|
||||
useEffect(() => {
|
||||
setLoadedSrc(null);
|
||||
}, [src]);
|
||||
|
||||
useEffect(() => {
|
||||
const image = imageRef.current;
|
||||
image.onerror = onError;
|
||||
return () => {
|
||||
image.onerror = noop;
|
||||
};
|
||||
}, [onError]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="module-quote__icon-container"
|
||||
style={
|
||||
loadedSrc ? { backgroundImage: `url('${escape(loadedSrc)}')` } : {}
|
||||
}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -14797,6 +14797,24 @@
|
|||
"updated": "2019-11-01T22:46:33.013Z",
|
||||
"reasonDetail": "Used for setting focus only"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/conversation/Quote.js",
|
||||
"line": " const imageRef = react_1.useRef(new Image());",
|
||||
"lineNumber": 227,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-01-20T21:30:08.430Z",
|
||||
"reasonDetail": "Doesn't touch the DOM."
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/conversation/Quote.tsx",
|
||||
"line": " const imageRef = useRef(new Image());",
|
||||
"lineNumber": 446,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-01-20T21:30:08.430Z",
|
||||
"reasonDetail": "Doesn't touch the DOM."
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/conversation/ReactionPicker.js",
|
||||
|
|
Loading…
Add table
Reference in a new issue