Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ export const AttachmentPreviewList = ({
if (!filteredAttachments.length && !location) return null;

return (
<div className='str-chat__attachment-preview-list'>
<div
className='str-chat__attachment-preview-list'
data-testid='attachment-preview-list'
>
{location && (
<GeolocationPreview
location={location}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import type { ComponentType } from 'react';
import React from 'react';
import { isLocalVoiceRecordingAttachment } from 'stream-chat';
import {
isLocalVoiceRecordingAttachment,
type LocalVoiceRecordingAttachment,
} from 'stream-chat';
import { useAttachmentsForPreview, useMessageComposer } from '../hooks';
import { AudioAttachmentPreview } from './AudioAttachmentPreview';
import type { VoiceRecordingPreviewProps } from './VoiceRecordingPreview';
import type { UploadAttachmentPreviewProps } from './types';

export type VoiceRecordingPreviewProps<CustomLocalMetadata = Record<string, unknown>> =
UploadAttachmentPreviewProps<LocalVoiceRecordingAttachment<CustomLocalMetadata>>;

export type VoiceRecordingPreviewSlotProps = {
/** Custom UI component for each voice recording preview in the slot; defaults to AudioAttachmentPreview */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ export type { ImageAttachmentPreviewProps } from './ImageAttachmentPreview';
export type { UploadAttachmentPreviewProps as AttachmentPreviewProps } from './types';
export type { UnsupportedAttachmentPreviewProps } from './UnsupportedAttachmentPreview';
export type { MediaAttachmentPreviewProps } from './MediaAttachmentPreview';
export type { VoiceRecordingPreviewProps } from './VoiceRecordingPreview';
export {
VoiceRecordingPreviewSlot,
type VoiceRecordingPreviewProps,
type VoiceRecordingPreviewSlotProps,
} from './VoiceRecordingPreviewSlot';
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,11 @@ export const RemoveAttachmentPreviewButton = ({
const { t } = useTranslationContext();
return (
<Button
appearance='solid'
aria-label={t('aria/Remove attachment')}
circular
className={clsx('str-chat__attachment-preview__remove-button', className)}
data-testid='preview-item-delete-button'
disabled={uploadState === 'uploading'}
type='button'
variant='secondary'
{...props}
>
<IconCrossSmall />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import React, { act } from 'react';
import { fireEvent, render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import { AttachmentPreviewList } from '../AttachmentPreviewList';
import {
AttachmentPreviewList,
VoiceRecordingPreviewSlot,
} from '../AttachmentPreviewList';
import { Channel } from '../../Channel';
import { Chat } from '../../Chat';

Expand All @@ -25,11 +28,13 @@ const RETRY_BTN_IMAGE_TEST_ID = 'image-preview-item-retry-button';
const DELETE_BTN_TEST_ID = 'file-preview-item-delete-button';
const DELETE_BTN_IMAGE_TEST_ID = 'image-preview-item-delete-button';
const LOADING_INDICATOR_TEST_ID = 'loading-indicator';
const ATTACHMENT_PREVIEW_LIST_TEST_ID = 'attachment-preview-list';

const renderComponent = async ({
attachments,
channel: customChannel,
client: customClient,
component: Component = AttachmentPreviewList,
components,
coords,
editedMessage,
Expand Down Expand Up @@ -61,10 +66,10 @@ const renderComponent = async ({
},
}}
>
<AttachmentPreviewList {...props} />
<Component {...props} />
</MessageProvider>
) : (
<AttachmentPreviewList {...props} />
<Component {...props} />
)}
</Channel>
</Chat>
Expand All @@ -82,7 +87,7 @@ describe('AttachmentPreviewList', () => {
it('does not render without attachments', async () => {
await renderComponent();

const attachmentList = screen.queryByTestId('attachment-list-scroll-container');
const attachmentList = screen.queryByTestId(ATTACHMENT_PREVIEW_LIST_TEST_ID);

expect(attachmentList).not.toBeInTheDocument();
});
Expand Down Expand Up @@ -123,6 +128,33 @@ describe('AttachmentPreviewList', () => {
},
);

it('renders voice recordings in the dedicated full-width slot', async () => {
const CustomVoiceRecordingPreview = () => (
<div data-testid='custom-voice-recording-preview'>voice preview</div>
);

await renderComponent({
attachments: [
generateVoiceRecordingAttachment({
localMetadata: {
id: 'voice-recording-attachment-id',
uploadState: 'finished',
},
title: 'voice-recording-finished',
}),
],
component: VoiceRecordingPreviewSlot,
props: {
VoiceRecordingPreview: CustomVoiceRecordingPreview,
},
});

const voicePreviewSlot = screen.getByTestId('voice-preview-slot');

expect(voicePreviewSlot).toBeInTheDocument();
expect(screen.getByTestId('custom-voice-recording-preview')).toBeInTheDocument();
});

// voiceRecording is rendered in VoiceRecordingPreviewSlot (REACT-794), not in AttachmentPreviewList
describe.each(['audio', 'file', 'image', 'unsupported', 'video'])(
'%s attachments rendering',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const FILE_PREVIEW_TEST_ID = 'attachment-preview-file';
const FILE_INPUT_TEST_ID = 'file-input';
const FILE_UPLOAD_RETRY_BTN_TEST_ID = 'file-preview-item-retry-button';
const SEND_BTN_TEST_ID = 'send-button';
const ATTACHMENT_PREVIEW_LIST_TEST_ID = 'attachment-list-scroll-container';
const ATTACHMENT_PREVIEW_LIST_TEST_ID = 'attachment-preview-list';
const UNKNOWN_ATTACHMENT_PREVIEW_TEST_ID = 'attachment-preview-unknown';

const cid = 'messaging:general';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,47 +11,33 @@ exports[`AttachmentPreviewList should render custom BaseImage component 1`] = `
>
<div
class="str-chat__attachment-preview-list"
data-testid="attachment-preview-list"
>
<div
class="str-chat__attachment-list-scroll-container"
data-testid="attachment-list-scroll-container"
aria-label="Download attachment"
class="str-chat__attachment-preview-media str-chat__attachment-preview-media--uploading"
data-testid="attachment-preview-media"
tabindex="-1"
>
<div
class="str-chat__attachment-preview-image"
data-testid="attachment-preview-image"
class="str-chat__attachment-preview-media__thumbnail-wrapper"
>
<button
aria-label="Remove attachment"
class="str-chat__attachment-preview-delete"
data-testid="image-preview-item-delete-button"
disabled=""
type="button"
>
<svg
data-testid="close-no-outline"
fill="none"
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41Z"
fill="black"
/>
</svg>
</button>
<img
alt="image-upload-1"
class="str-chat__attachment-preview-media__thumbnail"
data-testid="custom-base-image"
src="image-preview-uri"
title="image-upload-1"
/>
<div
class="str-chat__attachment-preview-image-loading"
class="str-chat__attachment-preview-media__overlay"
>
<div
class="str-chat__loading-indicator"
>
<svg
data-testid="loading-indicator"
height="17"
viewBox="0 0 30 30"
width="17"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
Expand Down Expand Up @@ -82,50 +68,54 @@ exports[`AttachmentPreviewList should render custom BaseImage component 1`] = `
</svg>
</div>
</div>
<img
alt="image-upload-1"
class="str-chat__attachment-preview-thumbnail"
data-testid="custom-base-image"
src="image-preview-uri"
title="image-upload-1"
/>
</div>
<div
class="str-chat__attachment-preview-image"
data-testid="attachment-preview-image"
<button
aria-label="Remove attachment"
class="str-chat__button str-chat__button--secondary str-chat__button--solid str-chat__button--circular str-chat__attachment-preview__remove-button"
data-testid="video-preview-item-delete-button"
disabled=""
type="button"
>
<button
aria-label="Remove attachment"
class="str-chat__attachment-preview-delete"
data-testid="image-preview-item-delete-button"
disabled=""
type="button"
<div
class="str-chat__button__content"
>
<svg
data-testid="close-no-outline"
fill="none"
height="24"
viewBox="0 0 24 24"
width="24"
class="str-chat__icon str-chat__icon--cross-small"
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41Z"
fill="black"
d="M10.4089 4.74281C10.6432 4.5085 11.0232 4.5085 11.2575 4.74281C11.4916 4.97709 11.4916 5.3562 11.2575 5.59047L8.84733 7.99965L11.2575 10.4088C11.4918 10.6431 11.4918 11.0231 11.2575 11.2575C11.0232 11.4918 10.6432 11.4918 10.4089 11.2575L7.99967 8.84731L5.59049 11.2575C5.35622 11.4916 4.97711 11.4916 4.74284 11.2575C4.50852 11.0231 4.50852 10.6431 4.74284 10.4088L7.15104 7.99965L4.74284 5.59047C4.50852 5.35616 4.50852 4.97713 4.74284 4.74281C4.97715 4.5085 5.35618 4.5085 5.59049 4.74281L7.99967 7.15102L10.4089 4.74281Z"
/>
</svg>
</button>
</div>
</button>
</div>
<div
aria-label="Download attachment"
class="str-chat__attachment-preview-media str-chat__attachment-preview-media--uploading"
data-testid="attachment-preview-media"
tabindex="-1"
>
<div
class="str-chat__attachment-preview-media__thumbnail-wrapper"
>
<img
alt="image-upload-2"
class="str-chat__attachment-preview-media__thumbnail"
data-testid="custom-base-image"
src="image-preview-uri"
title="image-upload-2"
/>
<div
class="str-chat__attachment-preview-image-loading"
class="str-chat__attachment-preview-media__overlay"
>
<div
class="str-chat__loading-indicator"
>
<svg
data-testid="loading-indicator"
height="17"
viewBox="0 0 30 30"
width="17"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
Expand Down Expand Up @@ -156,14 +146,28 @@ exports[`AttachmentPreviewList should render custom BaseImage component 1`] = `
</svg>
</div>
</div>
<img
alt="image-upload-2"
class="str-chat__attachment-preview-thumbnail"
data-testid="custom-base-image"
src="image-preview-uri"
title="image-upload-2"
/>
</div>
<button
aria-label="Remove attachment"
class="str-chat__button str-chat__button--secondary str-chat__button--solid str-chat__button--circular str-chat__attachment-preview__remove-button"
data-testid="video-preview-item-delete-button"
disabled=""
type="button"
>
<div
class="str-chat__button__content"
>
<svg
class="str-chat__icon str-chat__icon--cross-small"
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10.4089 4.74281C10.6432 4.5085 11.0232 4.5085 11.2575 4.74281C11.4916 4.97709 11.4916 5.3562 11.2575 5.59047L8.84733 7.99965L11.2575 10.4088C11.4918 10.6431 11.4918 11.0231 11.2575 11.2575C11.0232 11.4918 10.6432 11.4918 10.4089 11.2575L7.99967 8.84731L5.59049 11.2575C5.35622 11.4916 4.97711 11.4916 4.74284 11.2575C4.50852 11.0231 4.50852 10.6431 4.74284 10.4088L7.15104 7.99965L4.74284 5.59047C4.50852 5.35616 4.50852 4.97713 4.74284 4.74281C4.97715 4.5085 5.35618 4.5085 5.59049 4.74281L7.99967 7.15102L10.4089 4.74281Z"
/>
</svg>
</div>
</button>
</div>
</div>
</div>
Expand Down
26 changes: 15 additions & 11 deletions src/components/MessageInput/styling/AttachmentPreview.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@
--str-chat__attachment-preview-list-border-inline-end: none;
--str-chat__attachment-preview-list-box-shadow: none;

--str-chat__attachment-preview-close-icon-background: var(--base-black);
--str-chat__attachment-preview-close-icon-color: var(--control-remove-control-border);
--str-chat__attachment-preview-close-icon-background: var(--control-remove-control-bg);
--str-chat__attachment-preview-close-icon-color: var(--control-remove-control-icon);
--str-chat__attachment-preview-close-icon-border-color: var(
--control-remove-control-border
);
--str-chat__attachment-preview-retry-icon-color: var(--str-chat__primary-color);
--str-chat__attachment-preview-download-icon-color: var(--text-secondary);
--str-chat__attachment-preview-overlay-color: var(--background-core-overlay);
Expand Down Expand Up @@ -95,16 +98,15 @@
@include utils.component-layer-overrides('attachment-preview-list');
padding: var(--spacing-xxs);
display: flex;
align-items: center;
//justify-content: center;
align-items: flex-start;
align-content: flex-start;
flex-wrap: wrap;
justify-content: flex-start;
width: 100%;

min-width: 0;
max-width: 100%;
overflow-x: auto;
flex: 1 1 auto;
overflow-y: hidden;
overflow: visible;
flex: 0 0 auto;
gap: var(--spacing-md);
}

Expand All @@ -115,11 +117,11 @@
@include utils.component-layer-overrides('attachment-preview-file');
display: flex;
align-items: center;
flex: 0 1 auto;
gap: var(--spacing-sm);
padding: var(--spacing-md);
padding-right: var(--spacing-sm);
min-width: 224px;
max-width: 280px;
width: 290px;
}

.str-chat__attachment-preview-audio {
Expand Down Expand Up @@ -161,6 +163,7 @@

.str-chat__attachment-preview-media {
@include utils.component-layer-overrides('attachment-preview-image');
flex: 0 0 auto;
width: 72px;
height: 72px;
cursor: pointer;
Expand Down Expand Up @@ -283,7 +286,8 @@
.str-chat__attachment-preview-file__data {
display: flex;
align-items: center;
width: 160px;
width: min(160px, 100%);
max-width: 100%;
gap: var(--spacing-xxs);
color: var(--text-secondary);
font-weight: var(--typography-font-weight-regular);
Expand Down
Loading
Loading