From 5d6e3d5711b56eddb764e0ee8924b20c4e5ed5e2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 4 Mar 2021 20:07:48 -0700 Subject: [PATCH 1/3] UI refresh for uploaded files Fixes https://github.com/vector-im/element-web/issues/16557 Fixes https://github.com/vector-im/element-web/issues/9482 (technically) There's two changes in this: 1. The actual file body in the timeline now has a placeholder thing. 2. We're intentionally dropping all the "Travis uploaded a file" sender profile states. --- res/css/views/messages/_MFileBody.scss | 43 +++++++++++++++++++ res/themes/dark/css/_dark.scss | 4 ++ res/themes/legacy-dark/css/_legacy-dark.scss | 4 ++ .../legacy-light/css/_legacy-light.scss | 4 ++ res/themes/light/css/_light.scss | 4 ++ src/components/views/messages/MAudioBody.js | 2 +- src/components/views/messages/MFileBody.js | 26 ++++++++++- src/components/views/messages/MImageBody.js | 2 +- src/components/views/messages/MVideoBody.tsx | 2 +- .../views/messages/SenderProfile.js | 10 +---- src/components/views/rooms/EventTile.js | 7 +-- src/i18n/strings/en_EN.json | 3 -- 12 files changed, 88 insertions(+), 23 deletions(-) diff --git a/res/css/views/messages/_MFileBody.scss b/res/css/views/messages/_MFileBody.scss index 6cbce68745..e219c0c5e4 100644 --- a/res/css/views/messages/_MFileBody.scss +++ b/res/css/views/messages/_MFileBody.scss @@ -45,3 +45,46 @@ limitations under the License. * big the content of the iframe is. */ height: 1.5em; } + +.mx_MFileBody_info { + background-color: $message-body-panel-bg-color; + border-radius: 4px; + width: 270px; + padding: 8px; + color: $message-body-panel-fg-color; + + .mx_MFileBody_info_icon { + background-color: $message-body-panel-icon-bg-color; + border-radius: 20px; + display: inline-block; + width: 32px; + height: 32px; + position: relative; + vertical-align: middle; + margin-right: 12px; + + &::before { + content: ''; + mask-repeat: no-repeat; + mask-position: center; + mask-size: cover; + mask-image: url('$(res)/img/element-icons/room/composer/attach.svg'); + background-color: $message-body-panel-fg-color; + width: 13px; + height: 15px; + + position: absolute; + top: 8px; + left: 9px; + } + } + + .mx_MFileBody_info_filename { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + display: inline-block; + width: calc(100% - 32px - 12px); // 32px icon, 12px margin on the icon + vertical-align: middle; + } +} diff --git a/res/themes/dark/css/_dark.scss b/res/themes/dark/css/_dark.scss index 0de5e69782..a4648d2051 100644 --- a/res/themes/dark/css/_dark.scss +++ b/res/themes/dark/css/_dark.scss @@ -203,6 +203,10 @@ $breadcrumb-placeholder-bg-color: #272c35; $user-tile-hover-bg-color: $header-panel-bg-color; +$message-body-panel-bg-color: #21262c82; +$message-body-panel-icon-bg-color: #8e99a4; +$message-body-panel-fg-color: $primary-fg-color; + // Appearance tab colors $appearance-tab-border-color: $room-highlight-color; diff --git a/res/themes/legacy-dark/css/_legacy-dark.scss b/res/themes/legacy-dark/css/_legacy-dark.scss index 8c5f20178b..8752e41d18 100644 --- a/res/themes/legacy-dark/css/_legacy-dark.scss +++ b/res/themes/legacy-dark/css/_legacy-dark.scss @@ -198,6 +198,10 @@ $breadcrumb-placeholder-bg-color: #272c35; $user-tile-hover-bg-color: $header-panel-bg-color; +$message-body-panel-bg-color: #21262c82; +$message-body-panel-icon-bg-color: #8e99a4; +$message-body-panel-fg-color: $primary-fg-color; + // Appearance tab colors $appearance-tab-border-color: $room-highlight-color; diff --git a/res/themes/legacy-light/css/_legacy-light.scss b/res/themes/legacy-light/css/_legacy-light.scss index 3ba10a68ea..58b75f32aa 100644 --- a/res/themes/legacy-light/css/_legacy-light.scss +++ b/res/themes/legacy-light/css/_legacy-light.scss @@ -322,6 +322,10 @@ $breadcrumb-placeholder-bg-color: #e8eef5; $user-tile-hover-bg-color: $header-panel-bg-color; +$message-body-panel-bg-color: #e3e8f082; +$message-body-panel-icon-bg-color: #ffffff; +$message-body-panel-fg-color: $muted-fg-color; + // FontSlider colors $appearance-tab-border-color: $input-darker-bg-color; diff --git a/res/themes/light/css/_light.scss b/res/themes/light/css/_light.scss index 76bf2ddc21..fd2bfe4628 100644 --- a/res/themes/light/css/_light.scss +++ b/res/themes/light/css/_light.scss @@ -323,6 +323,10 @@ $breadcrumb-placeholder-bg-color: #e8eef5; $user-tile-hover-bg-color: $header-panel-bg-color; +$message-body-panel-bg-color: #e3e8f082; +$message-body-panel-icon-bg-color: #ffffff; +$message-body-panel-fg-color: $muted-fg-color; + // FontSlider colors $appearance-tab-border-color: $input-darker-bg-color; diff --git a/src/components/views/messages/MAudioBody.js b/src/components/views/messages/MAudioBody.js index 37f85a108f..587dee4513 100644 --- a/src/components/views/messages/MAudioBody.js +++ b/src/components/views/messages/MAudioBody.js @@ -105,7 +105,7 @@ export default class MAudioBody extends React.Component { return ( ); } diff --git a/src/components/views/messages/MFileBody.js b/src/components/views/messages/MFileBody.js index 770cd4fff3..676f0b7986 100644 --- a/src/components/views/messages/MFileBody.js +++ b/src/components/views/messages/MFileBody.js @@ -126,6 +126,12 @@ export default class MFileBody extends React.Component { onHeightChanged: PropTypes.func, /* the shape of the tile, used */ tileShape: PropTypes.string, + /* whether or not to show the default placeholder for the file. Defaults to true. */ + showGenericPlaceholder: PropTypes.bool, + }; + + static defaultProps = { + showGenericPlaceholder: true, }; constructor(props) { @@ -145,9 +151,10 @@ export default class MFileBody extends React.Component { * link text. * * @param {Object} content The "content" key of the matrix event. + * @param {boolean} withSize Whether to include size information. Default true. * @return {string} the human readable link text for the attachment. */ - presentableTextForFile(content) { + presentableTextForFile(content, withSize = true) { let linkText = _t("Attachment"); if (content.body && content.body.length > 0) { // The content body should be the name of the file including a @@ -155,7 +162,7 @@ export default class MFileBody extends React.Component { linkText = content.body; } - if (content.info && content.info.size) { + if (content.info && 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. @@ -218,6 +225,16 @@ export default class MFileBody extends React.Component { const fileSize = content.info ? content.info.size : null; const fileType = content.info ? content.info.mimetype : "application/octet-stream"; + let placeholder = null; + if (this.props.showGenericPlaceholder) { + placeholder = ( +
+ + {this.presentableTextForFile(content, false)} +
+ ); + } + if (isEncrypted) { if (this.state.decryptedBlob === null) { // Need to decrypt the attachment @@ -248,6 +265,7 @@ export default class MFileBody extends React.Component { // but it is not guaranteed between various browsers' settings. return ( + {placeholder}
{ _t("Decrypt %(text)s", { text: text }) } @@ -278,6 +296,7 @@ export default class MFileBody extends React.Component { // If the attachment is encrypted then put the link inside an iframe. return ( + {placeholder}
{ /* @@ -346,6 +365,7 @@ export default class MFileBody extends React.Component { if (this.props.tileShape === "file_grid") { return ( + {placeholder}
{ fileName } @@ -359,6 +379,7 @@ export default class MFileBody extends React.Component { } else { return ( + {placeholder}
@@ -371,6 +392,7 @@ export default class MFileBody extends React.Component { } else { const extra = text ? (': ' + text) : ''; return + {placeholder} { _t("Invalid file%(extra)s", { extra: extra }) } ; } diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index a8cdc17abf..771d12accd 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -452,7 +452,7 @@ export default class MImageBody extends React.Component { // Overidden by MStickerBody getFileBody() { - return ; + return ; } render() { diff --git a/src/components/views/messages/MVideoBody.tsx b/src/components/views/messages/MVideoBody.tsx index 9628f11809..ce4a4eda76 100644 --- a/src/components/views/messages/MVideoBody.tsx +++ b/src/components/views/messages/MVideoBody.tsx @@ -243,7 +243,7 @@ export default class MVideoBody extends React.PureComponent { onPlay={this.videoOnPlay} > - + ); } diff --git a/src/components/views/messages/SenderProfile.js b/src/components/views/messages/SenderProfile.js index afe2d6d118..e2bb1ff38d 100644 --- a/src/components/views/messages/SenderProfile.js +++ b/src/components/views/messages/SenderProfile.js @@ -25,7 +25,6 @@ import MatrixClientContext from "../../../contexts/MatrixClientContext"; export default class SenderProfile extends React.Component { static propTypes = { mxEvent: PropTypes.object.isRequired, // event whose sender we're showing - text: PropTypes.string, // Text to show. Defaults to sender name onClick: PropTypes.func, }; @@ -118,17 +117,10 @@ export default class SenderProfile extends React.Component { { flair } ; - const content = this.props.text ? - - - { _t(this.props.text, { senderName: () => nameElem }) } - - : nameFlair; - return (
- { content } + { nameFlair }
); diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 87fb190678..2009eb6d1c 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -768,15 +768,10 @@ export default class EventTile extends React.Component { } if (needsSenderProfile) { - let text = null; if (!this.props.tileShape || this.props.tileShape === 'reply' || this.props.tileShape === 'reply_preview') { - if (msgtype === 'm.image') text = _td('%(senderName)s sent an image'); - else if (msgtype === 'm.video') text = _td('%(senderName)s sent a video'); - else if (msgtype === 'm.file') text = _td('%(senderName)s uploaded a file'); sender = ; + enableFlair={this.props.enableFlair} />; } else { sender = ; } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index a1999acb3b..f3232416b1 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1430,9 +1430,6 @@ "Edit message": "Edit message", "Mod": "Mod", "This event could not be displayed": "This event could not be displayed", - "%(senderName)s sent an image": "%(senderName)s sent an image", - "%(senderName)s sent a video": "%(senderName)s sent a video", - "%(senderName)s uploaded a file": "%(senderName)s uploaded a file", "Your key share request has been sent - please check your other sessions for key share requests.": "Your key share request has been sent - please check your other sessions for key share requests.", "Key share requests are sent to your other sessions automatically. If you rejected or dismissed the key share request on your other sessions, click here to request the keys for this session again.": "Key share requests are sent to your other sessions automatically. If you rejected or dismissed the key share request on your other sessions, click here to request the keys for this session again.", "If your other sessions do not have the key for this message you will not be able to decrypt them.": "If your other sessions do not have the key for this message you will not be able to decrypt them.", From 8d143331a8d8fa72c89b8730f70b9b3ff9ba7009 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 4 Mar 2021 20:10:47 -0700 Subject: [PATCH 2/3] Appease the linter --- src/components/views/messages/SenderProfile.js | 1 - src/components/views/rooms/EventTile.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/views/messages/SenderProfile.js b/src/components/views/messages/SenderProfile.js index e2bb1ff38d..d2db05252c 100644 --- a/src/components/views/messages/SenderProfile.js +++ b/src/components/views/messages/SenderProfile.js @@ -18,7 +18,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import Flair from '../elements/Flair.js'; import FlairStore from '../../../stores/FlairStore'; -import { _t } from '../../../languageHandler'; import {getUserNameColorClass} from '../../../utils/FormattingUtils'; import MatrixClientContext from "../../../contexts/MatrixClientContext"; diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 2009eb6d1c..198b3427bc 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -22,7 +22,7 @@ import React, {createRef} from 'react'; import PropTypes from 'prop-types'; import classNames from "classnames"; import {EventType} from "matrix-js-sdk/src/@types/event"; -import { _t, _td } from '../../../languageHandler'; +import { _t } from '../../../languageHandler'; import * as TextForEvent from "../../../TextForEvent"; import * as sdk from "../../../index"; import dis from '../../../dispatcher/dispatcher'; From d7310bc5b36cb66abbee507ff74cea3f56592c70 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 4 Mar 2021 20:17:29 -0700 Subject: [PATCH 3/3] Remove dead classes --- res/css/views/rooms/_IRCLayout.scss | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/res/css/views/rooms/_IRCLayout.scss b/res/css/views/rooms/_IRCLayout.scss index 792c2f1f58..21baa795e6 100644 --- a/res/css/views/rooms/_IRCLayout.scss +++ b/res/css/views/rooms/_IRCLayout.scss @@ -181,8 +181,7 @@ $irc-line-height: $font-18px; > span { display: flex; - > .mx_SenderProfile_name, - > .mx_SenderProfile_aux { + > .mx_SenderProfile_name { overflow: hidden; text-overflow: ellipsis; min-width: var(--name-width); @@ -212,8 +211,7 @@ $irc-line-height: $font-18px; background: transparent; > span { - > .mx_SenderProfile_name, - > .mx_SenderProfile_aux { + > .mx_SenderProfile_name { min-width: inherit; } }