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

Commit

Permalink
[ICU-648] Fix download tooltip (#692)
Browse files Browse the repository at this point in the history
* fix download tooltip

* change text to `Download` only and change tooltip position closer to download icon

* fix conflicts

* removed unnecessary props and add constant for max filename length
  • Loading branch information
saturninoabril authored and GoldUniform committed Feb 6, 2018
1 parent e57ee0d commit ad3dd8f
Show file tree
Hide file tree
Showing 10 changed files with 505 additions and 313 deletions.
121 changes: 43 additions & 78 deletions components/file_attachment.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,19 @@ import PropTypes from 'prop-types';
import React from 'react';
import {getFileThumbnailUrl, getFileUrl} from 'mattermost-redux/utils/file_utils';

import Constants, {FileTypes} from 'utils/constants.jsx';
import * as FileUtils from 'utils/file_utils';
import * as Utils from 'utils/utils.jsx';
import {FileTypes} from 'utils/constants.jsx';
import {
canDownloadFiles,
trimFilename
} from 'utils/file_utils';
import {
fileSizeToString,
getFileType,
loadImage
} from 'utils/utils.jsx';

import FilenameOverlay from 'components/file_attachment/filename_overlay.jsx';
import FileThumbnail from 'components/file_attachment/file_thumbnail.jsx';
import DownloadIcon from 'components/svg/download_icon';

export default class FileAttachment extends React.PureComponent {
Expand Down Expand Up @@ -40,7 +48,7 @@ export default class FileAttachment extends React.PureComponent {
super(props);

this.state = {
loaded: Utils.getFileType(props.fileInfo.extension) !== FileTypes.IMAGE
loaded: getFileType(props.fileInfo.extension) !== FileTypes.IMAGE
};
}

Expand All @@ -53,7 +61,7 @@ export default class FileAttachment extends React.PureComponent {
const extension = nextProps.fileInfo.extension;

this.setState({
loaded: Utils.getFileType(extension) !== FileTypes.IMAGE && extension !== FileTypes.SVG
loaded: getFileType(extension) !== FileTypes.IMAGE && extension !== FileTypes.SVG
});
}
}
Expand All @@ -66,14 +74,14 @@ export default class FileAttachment extends React.PureComponent {

loadFiles = () => {
const fileInfo = this.props.fileInfo;
const fileType = Utils.getFileType(fileInfo.extension);
const fileType = getFileType(fileInfo.extension);

if (fileType === FileTypes.IMAGE) {
const thumbnailUrl = getFileThumbnailUrl(fileInfo.id);

Utils.loadImage(thumbnailUrl, this.handleImageLoaded);
loadImage(thumbnailUrl, this.handleImageLoaded);
} else if (fileInfo.extension === FileTypes.SVG) {
Utils.loadImage(getFileUrl(fileInfo.id), this.handleImageLoaded);
loadImage(getFileUrl(fileInfo.id), this.handleImageLoaded);
}
}

Expand All @@ -89,67 +97,14 @@ export default class FileAttachment extends React.PureComponent {
}

render() {
const fileInfo = this.props.fileInfo;
const fileName = fileInfo.name;
const fileUrl = getFileUrl(fileInfo.id);

let thumbnail;
if (this.state.loaded) {
const type = Utils.getFileType(fileInfo.extension);

if (type === FileTypes.IMAGE) {
let className = 'post-image';

if (fileInfo.width < Constants.THUMBNAIL_WIDTH && fileInfo.height < Constants.THUMBNAIL_HEIGHT) {
className += ' small';
} else {
className += ' normal';
}

let thumbnailUrl = getFileThumbnailUrl(fileInfo.id);
if (Utils.isGIFImage(fileInfo.extension) && !fileInfo.has_preview_image) {
thumbnailUrl = getFileUrl(fileInfo.id);
}

thumbnail = (
<div
className={className}
style={{
backgroundImage: `url(${thumbnailUrl})`,
backgroundSize: 'cover'
}}
/>
);
} else if (fileInfo.extension === FileTypes.SVG) {
thumbnail = (
<img
className='post-image normal'
src={getFileUrl(fileInfo.id)}
/>
);
} else {
thumbnail = <div className={'file-icon ' + Utils.getIconClassName(type)}/>;
}
} else {
thumbnail = <div className='post-image__load'/>;
}
const {
compactDisplay,
fileInfo,
index
} = this.props;

const canDownloadFiles = FileUtils.canDownloadFiles();

let downloadButton = null;
if (canDownloadFiles) {
downloadButton = (
<a
href={fileUrl}
download={fileName}
className='post-image__download'
target='_blank'
rel='noopener noreferrer'
>
<DownloadIcon/>
</a>
);
}
const trimmedFilename = trimFilename(fileInfo.name);
const canDownload = canDownloadFiles();

return (
<div className='post-image__column'>
Expand All @@ -158,26 +113,36 @@ export default class FileAttachment extends React.PureComponent {
href='#'
onClick={this.onAttachmentClick}
>
{thumbnail}
{this.state.loaded ? (
<FileThumbnail fileInfo={fileInfo}/>
) : (
<div className='post-image__load'/>
)}
</a>
<div className='post-image__details'>
<div
className='post-image__detail_wrapper'
onClick={this.onAttachmentClick}
>
<div className='post-image__detail'>
<FilenameOverlay
fileInfo={this.props.fileInfo}
index={this.props.index}
handleImageClick={this.props.handleImageClick}
compactDisplay={this.props.compactDisplay}
canDownload={canDownloadFiles}
/>
<span className={'post-image__name'}>
{trimmedFilename}
</span>
<span className='post-image__type'>{fileInfo.extension.toUpperCase()}</span>
<span className='post-image__size'>{Utils.fileSizeToString(fileInfo.size)}</span>
<span className='post-image__size'>{fileSizeToString(fileInfo.size)}</span>
</div>
</div>
{downloadButton}
{canDownload &&
<FilenameOverlay
fileInfo={fileInfo}
compactDisplay={compactDisplay}
canDownload={canDownload}
iconClass={'post-image__download'}
index={index}
>
<DownloadIcon/>
</FilenameOverlay>
}
</div>
</div>
);
Expand Down
67 changes: 67 additions & 0 deletions components/file_attachment/file_thumbnail.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.

import PropTypes from 'prop-types';
import React from 'react';

import {getFileThumbnailUrl, getFileUrl} from 'mattermost-redux/utils/file_utils';

import Constants, {FileTypes} from 'utils/constants.jsx';
import {
getFileType,
getIconClassName,
isGIFImage
} from 'utils/utils.jsx';

export default class FileThumbnail extends React.PureComponent {

static propTypes = {

/*
* File detailed information
*/
fileInfo: PropTypes.object.isRequired
}

render() {
const {fileInfo} = this.props;
const type = getFileType(fileInfo.extension);

let thumbnail;
if (type === FileTypes.IMAGE) {
let className = 'post-image';

if (fileInfo.width < Constants.THUMBNAIL_WIDTH && fileInfo.height < Constants.THUMBNAIL_HEIGHT) {
className += ' small';
} else {
className += ' normal';
}

let thumbnailUrl = getFileThumbnailUrl(fileInfo.id);
if (isGIFImage(fileInfo.extension) && !fileInfo.has_preview_image) {
thumbnailUrl = getFileUrl(fileInfo.id);
}

return (
<div
className={className}
style={{
backgroundImage: `url(${thumbnailUrl})`,
backgroundSize: 'cover'
}}
/>
);
} else if (fileInfo.extension === FileTypes.SVG) {
thumbnail = (
<img
className='post-image normal'
src={getFileUrl(fileInfo.id)}
/>
);
} else {
thumbnail = <div className={'file-icon ' + getIconClassName(type)}/>;
}

return thumbnail;
}
}
68 changes: 42 additions & 26 deletions components/file_attachment/filename_overlay.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {OverlayTrigger, Tooltip} from 'react-bootstrap';
import {getFileUrl} from 'mattermost-redux/utils/file_utils';

import AttachmentIcon from 'components/svg/attachment_icon';
import * as Utils from 'utils/utils.jsx';
import {trimFilename} from 'utils/file_utils';
import {localizeMessage} from 'utils/utils.jsx';

export default class FilenameOverlay extends React.PureComponent {
static propTypes = {
Expand Down Expand Up @@ -35,7 +36,17 @@ export default class FilenameOverlay extends React.PureComponent {
/*
* If it should display link to download on file name
*/
canDownload: PropTypes.bool
canDownload: PropTypes.bool,

/**
* Optional children like download icon
*/
children: PropTypes.element,

/**
* Optional class like for icon
*/
iconClass: PropTypes.string
};

onAttachmentClick = (e) => {
Expand All @@ -44,19 +55,20 @@ export default class FilenameOverlay extends React.PureComponent {
}

render() {
const fileInfo = this.props.fileInfo;
const {
canDownload,
children,
compactDisplay,
fileInfo,
iconClass
} = this.props;

const fileName = fileInfo.name;
const trimmedFilename = trimFilename(fileName);
const fileUrl = getFileUrl(fileInfo.id);

let trimmedFilename;
if (fileName.length > 35) {
trimmedFilename = fileName.substring(0, Math.min(35, fileName.length)) + '...';
} else {
trimmedFilename = fileName;
}

let filenameOverlay;
if (this.props.compactDisplay) {
if (compactDisplay) {
filenameOverlay = (
<OverlayTrigger
trigger={['hover', 'focus']}
Expand All @@ -75,24 +87,28 @@ export default class FilenameOverlay extends React.PureComponent {
</a>
</OverlayTrigger>
);
} else if (this.props.canDownload) {
} else if (canDownload) {
filenameOverlay = (
<OverlayTrigger
trigger={['hover', 'focus']}
delayShow={1000}
placement='top'
overlay={<Tooltip id='file-name__tooltip'>{Utils.localizeMessage('file_attachment.download', 'Download') + ' "' + fileName + '"'}</Tooltip>}
<a
href={fileUrl}
download={fileName}
className={iconClass || 'post-image__name'}
target='_blank'
rel='noopener noreferrer'
>
<a
href={fileUrl}
download={fileName}
className='post-image__name'
target='_blank'
rel='noopener noreferrer'
<OverlayTrigger
trigger={['hover', 'focus']}
delayShow={1000}
placement='top'
overlay={
<Tooltip id='file-name__tooltip'>
{localizeMessage('file_attachment.download', 'Download')}
</Tooltip>
}
>
{trimmedFilename}
</a>
</OverlayTrigger>
{children || trimmedFilename}
</OverlayTrigger>
</a>
);
} else {
filenameOverlay = (
Expand Down
2 changes: 1 addition & 1 deletion sass/components/_files.scss
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@
height: 100%;
justify-content: center;
line-height: 0;
padding-right: 10px;
padding: 0 5px;
position: absolute;
right: 0;
text-align: center;
Expand Down
Loading

0 comments on commit ad3dd8f

Please sign in to comment.