From b712595dd0f76b6da9a8e1b151e9b189946c89da Mon Sep 17 00:00:00 2001 From: Harshil Sharma <18575143+harshilsharma63@users.noreply.github.com> Date: Wed, 15 Apr 2026 10:26:03 +0530 Subject: [PATCH] Fixed the UI for compact mode file editing (#35878) * Fixed the UI for compact mode file editing * Added test * Updated file container height and font size for compact mode * Updated snapshot * File name truncation fix * lint fix * updated snapshot * Updated snapshot --- .../file_attachment.test.tsx.snap | 8 +++-- .../filename_overlay.test.tsx.snap | 6 +++- .../file_attachment/file_attachment.tsx | 2 +- .../file_attachment/filename_overlay.tsx | 2 +- .../file_preview/file_preview.test.tsx | 30 +++++++++++++++++++ .../components/file_preview/file_preview.tsx | 16 ++++++---- .../src/components/file_preview/index.ts | 4 +++ .../channels/src/sass/components/_files.scss | 27 +++++++++++++++++ .../channels/src/sass/components/_post.scss | 11 +++++-- webapp/channels/src/selectors/preferences.ts | 11 ++++++- 10 files changed, 104 insertions(+), 13 deletions(-) diff --git a/webapp/channels/src/components/file_attachment/__snapshots__/file_attachment.test.tsx.snap b/webapp/channels/src/components/file_attachment/__snapshots__/file_attachment.test.tsx.snap index 19b9dbc572c..161352fd1da 100644 --- a/webapp/channels/src/components/file_attachment/__snapshots__/file_attachment.test.tsx.snap +++ b/webapp/channels/src/components/file_attachment/__snapshots__/file_attachment.test.tsx.snap @@ -503,7 +503,7 @@ exports[`FileAttachment should match snapshot, with compact display 1`] = ` class="post-image__column" >
- test.pdf + + test.pdf +
diff --git a/webapp/channels/src/components/file_attachment/__snapshots__/filename_overlay.test.tsx.snap b/webapp/channels/src/components/file_attachment/__snapshots__/filename_overlay.test.tsx.snap index 2031fa83ab3..9616bfa8386 100644 --- a/webapp/channels/src/components/file_attachment/__snapshots__/filename_overlay.test.tsx.snap +++ b/webapp/channels/src/components/file_attachment/__snapshots__/filename_overlay.test.tsx.snap @@ -41,7 +41,11 @@ exports[`components/file_attachment/FilenameOverlay should match snapshot, compa - test_filename + + test_filename + `; diff --git a/webapp/channels/src/components/file_attachment/file_attachment.tsx b/webapp/channels/src/components/file_attachment/file_attachment.tsx index be2c58fc451..e6746f79410 100644 --- a/webapp/channels/src/components/file_attachment/file_attachment.tsx +++ b/webapp/channels/src/components/file_attachment/file_attachment.tsx @@ -403,7 +403,7 @@ export default function FileAttachment(props: Props) { ])} > {fileThumbnail} -
+
{fileDetail} {fileActions} {filenameOverlay} diff --git a/webapp/channels/src/components/file_attachment/filename_overlay.tsx b/webapp/channels/src/components/file_attachment/filename_overlay.tsx index 1ccf10b2778..0751ad6e0ac 100644 --- a/webapp/channels/src/components/file_attachment/filename_overlay.tsx +++ b/webapp/channels/src/components/file_attachment/filename_overlay.tsx @@ -78,7 +78,7 @@ export default class FilenameOverlay extends React.PureComponent { rel='noopener noreferrer' > - {trimmedFilename} + {trimmedFilename} ); diff --git a/webapp/channels/src/components/file_preview/file_preview.test.tsx b/webapp/channels/src/components/file_preview/file_preview.test.tsx index c1bca3d1687..17d9240adcf 100644 --- a/webapp/channels/src/components/file_preview/file_preview.test.tsx +++ b/webapp/channels/src/components/file_preview/file_preview.test.tsx @@ -149,4 +149,34 @@ describe('FilePreview', () => { expect(screen.getByAltText('file preview')).toHaveAttribute('src', getFileUrl(fileId)); }); + + test('should add compact classes when compactMode is true', () => { + const props = { + ...baseProps, + compactMode: true, + }; + + const {container} = renderWithContext( + , + ); + + expect(container.querySelector('.file-preview.post-image__column.compact')).toBeInTheDocument(); + expect(container.querySelector('.post-image__detail.compact')).toBeInTheDocument(); + expect(container.querySelector('.file-preview__remove.compact')).toBeInTheDocument(); + }); + + test('should not add compact classes when compactMode is false', () => { + const props = { + ...baseProps, + compactMode: false, + }; + + const {container} = renderWithContext( + , + ); + + expect(container.querySelector('.file-preview.post-image__column.compact')).not.toBeInTheDocument(); + expect(container.querySelector('.post-image__detail.compact')).not.toBeInTheDocument(); + expect(container.querySelector('.file-preview__remove.compact')).not.toBeInTheDocument(); + }); }); diff --git a/webapp/channels/src/components/file_preview/file_preview.tsx b/webapp/channels/src/components/file_preview/file_preview.tsx index 85eba9c429f..cd08ca33f0d 100644 --- a/webapp/channels/src/components/file_preview/file_preview.tsx +++ b/webapp/channels/src/components/file_preview/file_preview.tsx @@ -1,6 +1,7 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. +import classNames from 'classnames'; import React from 'react'; import type {ReactNode} from 'react'; @@ -28,7 +29,8 @@ type Props = { fileInfos: FilePreviewInfo[]; uploadsInProgress?: string[]; uploadsProgressPercent?: {[clientID: string]: FilePreviewInfo}; -} + compactMode?: boolean; +}; export default class FilePreview extends React.PureComponent { static defaultProps = { @@ -85,6 +87,10 @@ export default class FilePreview extends React.PureComponent { previewImage =
; } + if (this.props.compactMode) { + className += ' compact'; + } + previews.push(
{
-
+
{info.extension && {info.extension.toUpperCase()}} @@ -108,7 +114,7 @@ export default class FilePreview extends React.PureComponent {
{Boolean(this.props.onRemove) && ( @@ -138,7 +144,7 @@ export default class FilePreview extends React.PureComponent { } return ( -
+
{previews}
); diff --git a/webapp/channels/src/components/file_preview/index.ts b/webapp/channels/src/components/file_preview/index.ts index 58c441b7f8d..d08fe27b7b0 100644 --- a/webapp/channels/src/components/file_preview/index.ts +++ b/webapp/channels/src/components/file_preview/index.ts @@ -5,15 +5,19 @@ import {connect} from 'react-redux'; import {getConfig} from 'mattermost-redux/selectors/entities/general'; +import {isCompactMode} from 'selectors/preferences'; + import type {GlobalState} from 'types/store'; import FilePreview from './file_preview'; function mapStateToProps(state: GlobalState) { const config = getConfig(state); + const compactMode = isCompactMode(state); return { enableSVGs: config.EnableSVGs === 'true', + compactMode, }; } diff --git a/webapp/channels/src/sass/components/_files.scss b/webapp/channels/src/sass/components/_files.scss index 3bac076ceb7..5e81cac0fc2 100644 --- a/webapp/channels/src/sass/components/_files.scss +++ b/webapp/channels/src/sass/components/_files.scss @@ -15,6 +15,10 @@ overflow-x: auto; overflow-y: hidden; white-space: nowrap; + + &.compact { + height: unset; + } } .file-preview { @@ -38,11 +42,20 @@ margin-top: -16px; margin-left: -16px; } + + &.compact { + overflow: hidden !important; + } } .app__body { .file-preview__remove { position: absolute; + + &.compact { + position: unset; + } + top: 4px; right: 4px; display: flex; @@ -494,6 +507,12 @@ font-size: 12px; text-align: left; + &.compact { + .post-image__name { + font-size: 12px; + } + } + .post-image__archived-name { align-items: center; justify-content: start; @@ -537,6 +556,14 @@ line-height: normal; text-overflow: ellipsis; + &.compact { + height: unset; + + .post-image__name { + font-size: 12px; + } + } + .post-image__name { display: block; overflow: hidden; diff --git a/webapp/channels/src/sass/components/_post.scss b/webapp/channels/src/sass/components/_post.scss index f366d92066f..08fe147268f 100644 --- a/webapp/channels/src/sass/components/_post.scss +++ b/webapp/channels/src/sass/components/_post.scss @@ -949,6 +949,7 @@ display: flex; width: 100%; + max-width: 100%; align-items: center; justify-content: flex-start; padding: 0 5px; @@ -961,6 +962,12 @@ font-size: 0.9em; opacity: 0.5; } + + .post-image__filename { + display: inline; + overflow: hidden; + text-overflow: ellipsis; + } } a { @@ -1673,11 +1680,11 @@ } } - .post__translation-icon-processing { + .post__translation-icon-processing { color: rgba(var(--center-channel-color-rgb), 0.73); font-size: 10px; line-height: 16px; - + .LoadingSpinner.with-text .spinner { margin-right: 3px; } diff --git a/webapp/channels/src/selectors/preferences.ts b/webapp/channels/src/selectors/preferences.ts index 6749d88687f..7a254cbcd82 100644 --- a/webapp/channels/src/selectors/preferences.ts +++ b/webapp/channels/src/selectors/preferences.ts @@ -1,7 +1,7 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import {getBool as getBoolPreference} from 'mattermost-redux/selectors/entities/preferences'; +import {get, getBool as getBoolPreference} from 'mattermost-redux/selectors/entities/preferences'; import {Preferences} from 'utils/constants'; @@ -33,3 +33,12 @@ export const isUseMilitaryTime = (state: GlobalState) => { false, ); }; + +export const isCompactMode = (state: GlobalState) => { + return get( + state, + Preferences.CATEGORY_DISPLAY_SETTINGS, + Preferences.MESSAGE_DISPLAY, + Preferences.MESSAGE_DISPLAY_DEFAULT, + ) === Preferences.MESSAGE_DISPLAY_COMPACT; +};