Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Show file name and size on images on hover #6511

Merged
merged 14 commits into from
May 14, 2022
5 changes: 5 additions & 0 deletions res/css/views/elements/_ImageView.scss
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ $button-gap: 24px;
font-weight: bold;
}

.mx_ImageView_title {
color: $lightbox-fg-color;
font-size: $font-12px;
}

.mx_ImageView_toolbar {
padding-right: 16px;
pointer-events: initial;
Expand Down
22 changes: 22 additions & 0 deletions res/css/views/messages/_MImageBody.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,28 @@ limitations under the License.

$timeline-image-border-radius: 8px;

.mx_MImageBody_banner {
position: absolute;
bottom: 4px;
left: 4px;
padding: 4px;
border-radius: $timeline-image-border-radius;
font-size: $font-15px;

pointer-events: none; // let the cursor go through to the media underneath

// Trying to match the width of the image is surprisingly difficult, so arbitrarily break it off early.
max-width: min(100%, 350px);

text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;

// Hardcoded colours because it's the same on all themes
background-color: rgba(0, 0, 0, 0.6);
color: #ffffff;
}

.mx_MImageBody_placeholder {
// Position the placeholder on top of the thumbnail, so that the reveal animation can work
position: absolute;
Expand Down
4 changes: 4 additions & 0 deletions src/components/views/elements/ImageView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import UIStore from '../../../stores/UIStore';
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
import { presentableTextForFile } from "../../../utils/FileUtils";

// Max scale to keep gaps around the image
const MAX_SCALE = 0.95;
Expand Down Expand Up @@ -546,6 +547,9 @@ export default class ImageView extends React.Component<IProps, IState> {
>
<div className="mx_ImageView_panel">
{ info }
<div className="mx_ImageView_title">
{ presentableTextForFile(this.props.mxEvent.getContent(), _t("Image"), true) }
</div>
<div className="mx_ImageView_toolbar">
{ zoomOutButton }
{ zoomInButton }
Expand Down
2 changes: 1 addition & 1 deletion src/components/views/messages/MFileBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ export default class MFileBody extends React.Component<IProps, IState> {
</a>
{ this.context.timelineRenderingType === TimelineRenderingType.File && (
<div className="mx_MImageBody_size">
{ this.content.info && this.content.info.size ? filesize(this.content.info.size) : "" }
{ this.content.info?.size ? filesize(this.content.info.size) : "" }
</div>
) }
</div> }
Expand Down
17 changes: 17 additions & 0 deletions src/components/views/messages/MImageBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { ImageSize, suggestedSize as suggestedImageSize } from "../../../setting
import { MatrixClientPeg } from '../../../MatrixClientPeg';
import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext";
import { blobIsAnimated, mayBeAnimated } from '../../../utils/Image';
import { presentableTextForFile } from "../../../utils/FileUtils";

enum Placeholder {
NoImage,
Expand Down Expand Up @@ -446,6 +447,21 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
gifLabel = <p className="mx_MImageBody_gifLabel">GIF</p>;
}

let banner: JSX.Element;
const isTimeline = [
TimelineRenderingType.Room,
TimelineRenderingType.Search,
TimelineRenderingType.Thread,
TimelineRenderingType.Notification,
].includes(this.context.timelineRenderingType);
Comment on lines +451 to +456
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this trying to make sure we don't show the banner in the file panel or something else? Perhaps a comment would help here to be a little more explicit about why are we doing this

if (this.state.showImage && this.state.hover && isTimeline) {
banner = (
<span className="mx_MImageBody_banner">
{ presentableTextForFile(content, _t("Image"), true, true) }
</span>
);
}

const classes = classNames({
'mx_MImageBody_placeholder': true,
'mx_MImageBody_placeholder--blurhash': this.props.mxEvent.getContent().info?.[BLURHASH_FIELD],
Expand Down Expand Up @@ -473,6 +489,7 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
<div style={sizing}>
{ img }
{ gifLabel }
{ banner }
</div>

{ /* HACK: This div fills out space while the image loads, to prevent scroll jumps */ }
Expand Down
2 changes: 1 addition & 1 deletion src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -2134,9 +2134,9 @@
"Error decrypting attachment": "Error decrypting attachment",
"Decrypt %(text)s": "Decrypt %(text)s",
"Invalid file%(extra)s": "Invalid file%(extra)s",
"Image": "Image",
"Error decrypting image": "Error decrypting image",
"Show image": "Show image",
"Image": "Image",
"Join the conference at the top of this room": "Join the conference at the top of this room",
"Join the conference from the room information card on the right": "Join the conference from the room information card on the right",
"Video conference ended by %(senderName)s": "Video conference ended by %(senderName)s",
Expand Down
4 changes: 2 additions & 2 deletions src/utils/FileUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function presentableTextForFile(
shortened = false,
): string {
let text = fallbackText;
if (content.body && content.body.length > 0) {
if (content.body?.length > 0) {
// The content body should be the name of the file including a
// file extension.
text = content.body;
Expand All @@ -58,7 +58,7 @@ export function presentableTextForFile(
text = `${fileName}...${extension}`;
}

if (content.info && content.info.size && withSize) {
if (content.info?.size && withSize) {
// If we know the size of the file then add it as human readable
// string to the end of the link text so that the user knows how
// big a file they are downloading.
Expand Down