Skip to content

Commit

Permalink
perf(package-size): remove react-file-utils package (#2088)
Browse files Browse the repository at this point in the history
* Move react-file-utils files to chat

* Update import paths

* Remove react-file-utils from packages

* Refactor - reuse UploadButton, move icons
  • Loading branch information
arnautov-anton authored Sep 8, 2023
1 parent a319aa6 commit 1258e09
Show file tree
Hide file tree
Showing 39 changed files with 1,831 additions and 37 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
"prop-types": "^15.7.2",
"react-dropzone": "^14.2.3",
"react-fast-compare": "^3.2.2",
"react-file-utils": "^1.2.0",
"react-image-gallery": "1.2.12",
"react-is": "^18.1.0",
"react-markdown": "^8.0.7",
Expand Down
1 change: 0 additions & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ const externalDependencies = [
'pretty-bytes',
'prop-types',
'react-fast-compare',
/react-file-utils/,
'react-images',
'react-image-gallery',
'react-is',
Expand Down
2 changes: 1 addition & 1 deletion src/components/Attachment/FileAttachment.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { FileIcon } from 'react-file-utils';
import { FileIcon } from '../ReactFileUtilities';
import type { Attachment } from 'stream-chat';

import { DownloadButton } from './DownloadButton';
Expand Down
2 changes: 1 addition & 1 deletion src/components/MessageInput/AttachmentPreviewList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useCallback } from 'react';
import { FileIcon } from 'react-file-utils';
import { FileIcon } from '../ReactFileUtilities';

import { useMessageInputContext } from '../../context/MessageInputContext';
import { useFileState } from './hooks/useFileState';
Expand Down
2 changes: 1 addition & 1 deletion src/components/MessageInput/DropzoneProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { PropsWithChildren } from 'react';
import { ImageDropzone } from 'react-file-utils';
import { ImageDropzone } from '../ReactFileUtilities';

import { useCooldownTimer } from './hooks/useCooldownTimer';
import { useCreateMessageInputContext } from './hooks/useCreateMessageInputContext';
Expand Down
2 changes: 1 addition & 1 deletion src/components/MessageInput/EditMessageForm.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect } from 'react';
import { FileUploadButton, ImageDropzone } from 'react-file-utils';
import { FileUploadButton, ImageDropzone } from '../ReactFileUtilities';

import { EmojiPicker } from './EmojiPicker';
import {
Expand Down
2 changes: 1 addition & 1 deletion src/components/MessageInput/MessageInputFlat.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect, useMemo, useState } from 'react';
import { FileUploadButton, ImageDropzone, UploadButton } from 'react-file-utils';
import { FileUploadButton, ImageDropzone, UploadButton } from '../ReactFileUtilities';
import type { Event } from 'stream-chat';
import clsx from 'clsx';
import { usePopper } from 'react-popper';
Expand Down
2 changes: 1 addition & 1 deletion src/components/MessageInput/MessageInputSmall.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect } from 'react';
import { FileUploadButton, ImageDropzone } from 'react-file-utils';
import { FileUploadButton, ImageDropzone } from '../ReactFileUtilities';
import type { Event } from 'stream-chat';

import { EmojiPicker } from './EmojiPicker';
Expand Down
2 changes: 1 addition & 1 deletion src/components/MessageInput/UploadsPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { FilePreviewer, ImagePreviewer } from 'react-file-utils';
import { FilePreviewer, ImagePreviewer } from '../ReactFileUtilities';

import { useChannelStateContext } from '../../context/ChannelStateContext';
import { useMessageInputContext } from '../../context/MessageInputContext';
Expand Down
2 changes: 1 addition & 1 deletion src/components/MessageInput/hooks/useAttachments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useFileUploads } from './useFileUploads';

import { useChannelStateContext } from '../../../context/ChannelStateContext';

import type { FileLike } from 'react-file-utils';
import type { FileLike } from '../../ReactFileUtilities';

import type { MessageInputProps } from '../MessageInput';
import type { MessageInputReducerAction, MessageInputState } from './useMessageInputState';
Expand Down
2 changes: 1 addition & 1 deletion src/components/MessageInput/hooks/useMessageInputState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { useSubmitHandler } from './useSubmitHandler';
import { usePasteHandler } from './usePasteHandler';

import type { EmojiData, NimbleEmojiIndex } from 'emoji-mart';
import type { FileLike } from 'react-file-utils';
import type { FileLike } from '../../ReactFileUtilities';
import type { Attachment, Message, UserResponse } from 'stream-chat';

import type { MessageInputProps } from '../MessageInput';
Expand Down
6 changes: 5 additions & 1 deletion src/components/MessageInput/hooks/usePasteHandler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { useCallback } from 'react';
import { dataTransferItemsHaveFiles, dataTransferItemsToFiles, FileLike } from 'react-file-utils';
import {
dataTransferItemsHaveFiles,
dataTransferItemsToFiles,
FileLike,
} from '../../ReactFileUtilities';

export const usePasteHandler = (
uploadNewFiles: (files: FileList | FileLike[] | File[]) => void,
Expand Down
2 changes: 1 addition & 1 deletion src/components/MessageInput/hooks/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ImageUpload } from 'react-file-utils';
import type { ImageUpload } from '../../ReactFileUtilities';
import type { AppSettingsAPIResponse, FileUploadConfig, UserResponse } from 'stream-chat';

import type { ChannelActionContextValue } from '../../../context/ChannelActionContext';
Expand Down
50 changes: 50 additions & 0 deletions src/components/ReactFileUtilities/FileIcon/FileIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from 'react';

import { iconMap, IconType, IconVersion } from './iconMap';

export type FileIconProps = {
big?: boolean;
className?: string;
filename?: string;
mimeType?: string;
size?: number; // big icon on sent attachment
sizeSmall?: number; // small icon on file upload preview
type?: IconType;
version?: IconVersion;
};

export function mimeTypeToIcon(
type: IconType = 'standard',
version: IconVersion = '1',
mimeType?: string,
) {
const theMap = iconMap[version]?.[type] || iconMap[version]['standard'];

if (!mimeType) return theMap.fallback;

const icon = theMap[mimeType];
if (icon) return icon;

if (mimeType.startsWith('audio/')) return theMap['audio/'];
if (mimeType.startsWith('video/')) return theMap['video/'];
if (mimeType.startsWith('image/')) return theMap['image/'];
if (mimeType.startsWith('text/')) return theMap['text/'];

return theMap.fallback;
}

export const FileIcon = (props: FileIconProps) => {
const {
big = false,
mimeType,
size = 50,
sizeSmall = 20,
type = 'standard',
version = '1',
...rest
} = props;

const Icon = mimeTypeToIcon(type, version, mimeType);

return <Icon {...rest} size={big ? size : sizeSmall} />;
};
185 changes: 185 additions & 0 deletions src/components/ReactFileUtilities/FileIcon/FileIconSet/v1.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
/**
* Font Awesome Free 5.15.3 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
*/
import React, { ComponentPropsWithoutRef } from 'react';

export type IconPropsV1 = { size?: number } & ComponentPropsWithoutRef<'svg'>;

const DEFAULT_SIZE = 20;

export const FilePdfIcon = ({ size = DEFAULT_SIZE, ...props }: IconPropsV1) => (
<svg
className='rfu-file-icon--small fa-file-pdf'
height={size}
viewBox='0 0 384 512'
width={size}
xmlns='http://www.w3.org/2000/svg'
{...props}
>
<path
d='M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm250.2-143.7c-12.2-12-47-8.7-64.4-6.5-17.2-10.5-28.7-25-36.8-46.3 3.9-16.1 10.1-40.6 5.4-56-4.2-26.2-37.8-23.6-42.6-5.9-4.4 16.1-.4 38.5 7 67.1-10 23.9-24.9 56-35.4 74.4-20 10.3-47 26.2-51 46.2-3.3 15.8 26 55.2 76.1-31.2 22.4-7.4 46.8-16.5 68.4-20.1 18.9 10.2 41 17 55.8 17 25.5 0 28-28.2 17.5-38.7zm-198.1 77.8c5.1-13.7 24.5-29.5 30.4-35-19 30.3-30.4 35.7-30.4 35zm81.6-190.6c7.4 0 6.7 32.1 1.8 40.8-4.4-13.9-4.3-40.8-1.8-40.8zm-24.4 136.6c9.7-16.9 18-37 24.7-54.7 8.3 15.1 18.9 27.2 30.1 35.5-20.8 4.3-38.9 13.1-54.8 19.2zm131.6-5s-5 6-37.3-7.8c35.1-2.6 40.9 5.4 37.3 7.8z'
fill='#f82903'
/>
</svg>
);

export const FileWordIcon = ({ size = DEFAULT_SIZE, ...props }: IconPropsV1) => (
<svg
className='rfu-file-icon--small fa-file-word'
height={size}
viewBox='0 0 384 512'
width={size}
xmlns='http://www.w3.org/2000/svg'
{...props}
>
<path
d='M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm220.1-208c-5.7 0-10.6 4-11.7 9.5-20.6 97.7-20.4 95.4-21 103.5-.2-1.2-.4-2.6-.7-4.3-.8-5.1.3.2-23.6-99.5-1.3-5.4-6.1-9.2-11.7-9.2h-13.3c-5.5 0-10.3 3.8-11.7 9.1-24.4 99-24 96.2-24.8 103.7-.1-1.1-.2-2.5-.5-4.2-.7-5.2-14.1-73.3-19.1-99-1.1-5.6-6-9.7-11.8-9.7h-16.8c-7.8 0-13.5 7.3-11.7 14.8 8 32.6 26.7 109.5 33.2 136 1.3 5.4 6.1 9.1 11.7 9.1h25.2c5.5 0 10.3-3.7 11.6-9.1l17.9-71.4c1.5-6.2 2.5-12 3-17.3l2.9 17.3c.1.4 12.6 50.5 17.9 71.4 1.3 5.3 6.1 9.1 11.6 9.1h24.7c5.5 0 10.3-3.7 11.6-9.1 20.8-81.9 30.2-119 34.5-136 1.9-7.6-3.8-14.9-11.6-14.9h-15.8z'
fill='#2c599d'
/>
</svg>
);

export const FilePowerPointIcon = ({ size = DEFAULT_SIZE, ...props }) => (
<svg
className='rfu-file-icon--small fa-file-powerpoint'
height={size}
viewBox='0 0 384 512'
width={size}
xmlns='http://www.w3.org/2000/svg'
{...props}
>
<path
d='M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm72-60V236c0-6.6 5.4-12 12-12h69.2c36.7 0 62.8 27 62.8 66.3 0 74.3-68.7 66.5-95.5 66.5V404c0 6.6-5.4 12-12 12H132c-6.6 0-12-5.4-12-12zm48.5-87.4h23c7.9 0 13.9-2.4 18.1-7.2 8.5-9.8 8.4-28.5.1-37.8-4.1-4.6-9.9-7-17.4-7h-23.9v52z'
fill='#cb4a32'
/>
</svg>
);

export const FileExcelIcon = ({ size = DEFAULT_SIZE, ...props }: IconPropsV1) => (
<svg
className='rfu-file-icon--small fa-file-excel'
height={size}
viewBox='0 0 384 512'
width={size}
xmlns='http://www.w3.org/2000/svg'
{...props}
>
<path
d='M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm212-240h-28.8c-4.4 0-8.4 2.4-10.5 6.3-18 33.1-22.2 42.4-28.6 57.7-13.9-29.1-6.9-17.3-28.6-57.7-2.1-3.9-6.2-6.3-10.6-6.3H124c-9.3 0-15 10-10.4 18l46.3 78-46.3 78c-4.7 8 1.1 18 10.4 18h28.9c4.4 0 8.4-2.4 10.5-6.3 21.7-40 23-45 28.6-57.7 14.9 30.2 5.9 15.9 28.6 57.7 2.1 3.9 6.2 6.3 10.6 6.3H260c9.3 0 15-10 10.4-18L224 320c.7-1.1 30.3-50.5 46.3-78 4.7-8-1.1-18-10.3-18z'
fill='#207245'
/>
</svg>
);

export const FileArchiveIcon = ({ size = DEFAULT_SIZE, ...props }: IconPropsV1) => (
<svg
className='rfu-file-icon--small fa-file-archive'
height={size}
viewBox='0 0 384 512'
width={size}
xmlns='http://www.w3.org/2000/svg'
{...props}
>
<path
d='M128.3 160v32h32v-32zm64-96h-32v32h32zm-64 32v32h32V96zm64 32h-32v32h32zm177.6-30.1L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM256 51.9l76.1 76.1H256zM336 464H48V48h79.7v16h32V48H208v104c0 13.3 10.7 24 24 24h104zM194.2 265.7c-1.1-5.6-6-9.7-11.8-9.7h-22.1v-32h-32v32l-19.7 97.1C102 385.6 126.8 416 160 416c33.1 0 57.9-30.2 51.5-62.6zm-33.9 124.4c-17.9 0-32.4-12.1-32.4-27s14.5-27 32.4-27 32.4 12.1 32.4 27-14.5 27-32.4 27zm32-198.1h-32v32h32z'
fill='#414D54'
/>
</svg>
);

export const FileCodeIcon = ({ size = DEFAULT_SIZE, ...props }: IconPropsV1) => (
<svg
className='rfu-file-icon--small fa-file-code'
height={size}
viewBox='0 0 384 512'
width={size}
xmlns='http://www.w3.org/2000/svg'
{...props}
>
<path
d='M149.9 349.1l-.2-.2-32.8-28.9 32.8-28.9c3.6-3.2 4-8.8.8-12.4l-.2-.2-17.4-18.6c-3.4-3.6-9-3.7-12.4-.4l-57.7 54.1c-3.7 3.5-3.7 9.4 0 12.8l57.7 54.1c1.6 1.5 3.8 2.4 6 2.4 2.4 0 4.8-1 6.4-2.8l17.4-18.6c3.3-3.5 3.1-9.1-.4-12.4zm220-251.2L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM256 51.9l76.1 76.1H256zM336 464H48V48h160v104c0 13.3 10.7 24 24 24h104zM209.6 214c-4.7-1.4-9.5 1.3-10.9 6L144 408.1c-1.4 4.7 1.3 9.6 6 10.9l24.4 7.1c4.7 1.4 9.6-1.4 10.9-6L240 231.9c1.4-4.7-1.3-9.6-6-10.9zm24.5 76.9l.2.2 32.8 28.9-32.8 28.9c-3.6 3.2-4 8.8-.8 12.4l.2.2 17.4 18.6c3.3 3.5 8.9 3.7 12.4.4l57.7-54.1c3.7-3.5 3.7-9.4 0-12.8l-57.7-54.1c-3.5-3.3-9.1-3.2-12.4.4l-17.4 18.6c-3.3 3.5-3.1 9.1.4 12.4z'
fill='#414D54'
/>
</svg>
);

export const FileAudioIcon = ({ size = DEFAULT_SIZE, ...props }: IconPropsV1) => (
<svg
className='rfu-file-icon--small fa-file-audio'
height={size}
viewBox='0 0 384 512'
width={size}
xmlns='http://www.w3.org/2000/svg'
{...props}
>
<path
d='M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM332.118 128H256V51.882L332.118 128zM48 464V48h160v104c0 13.255 10.745 24 24 24h104v288H48zm144-76.024c0 10.691-12.926 16.045-20.485 8.485L136 360.486h-28c-6.627 0-12-5.373-12-12v-56c0-6.627 5.373-12 12-12h28l35.515-36.947c7.56-7.56 20.485-2.206 20.485 8.485v135.952zm41.201-47.13c9.051-9.297 9.06-24.133.001-33.439-22.149-22.752 12.235-56.246 34.395-33.481 27.198 27.94 27.212 72.444.001 100.401-21.793 22.386-56.947-10.315-34.397-33.481z'
fill='#414D54'
/>
</svg>
);

export const FileVideoIcon = ({ size = DEFAULT_SIZE, ...props }: IconPropsV1) => (
<svg
className='rfu-file-icon--small fa-file-video'
height={size}
viewBox='0 0 384 512'
width={size}
xmlns='http://www.w3.org/2000/svg'
{...props}
>
<path
d='M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM332.118 128H256V51.882L332.118 128zM48 464V48h160v104c0 13.255 10.745 24 24 24h104v288H48zm228.687-211.303L224 305.374V268c0-11.046-8.954-20-20-20H100c-11.046 0-20 8.954-20 20v104c0 11.046 8.954 20 20 20h104c11.046 0 20-8.954 20-20v-37.374l52.687 52.674C286.704 397.318 304 390.28 304 375.986V264.011c0-14.311-17.309-21.319-27.313-11.314z'
fill='#414D54'
/>
</svg>
);

export const FileImageIcon = ({ size = DEFAULT_SIZE, ...props }: IconPropsV1) => (
<svg
className='rfu-file-icon--small fa-file-image'
height={size}
viewBox='0 0 384 512'
width={size}
xmlns='http://www.w3.org/2000/svg'
{...props}
>
<path
d='M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm32-48h224V288l-23.5-23.5c-4.7-4.7-12.3-4.7-17 0L176 352l-39.5-39.5c-4.7-4.7-12.3-4.7-17 0L80 352v64zm48-240c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48z'
fill='#414D54'
/>
</svg>
);

export const FileAltIcon = ({ size = DEFAULT_SIZE, ...props }: IconPropsV1) => (
<svg
className='rfu-file-icon--small fa-file-alt'
height={size}
viewBox='0 0 384 512'
width={size}
xmlns='http://www.w3.org/2000/svg'
{...props}
>
<path
d='M288 248v28c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-28c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm-12 72H108c-6.6 0-12 5.4-12 12v28c0 6.6 5.4 12 12 12h168c6.6 0 12-5.4 12-12v-28c0-6.6-5.4-12-12-12zm108-188.1V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V48C0 21.5 21.5 0 48 0h204.1C264.8 0 277 5.1 286 14.1L369.9 98c9 8.9 14.1 21.2 14.1 33.9zm-128-80V128h76.1L256 51.9zM336 464V176H232c-13.3 0-24-10.7-24-24V48H48v416h288z'
fill='#414D54'
/>
</svg>
);

export const FileFallbackIcon = ({ size = DEFAULT_SIZE, ...props }: IconPropsV1) => (
<svg
className='rfu-file-icon--small fa-file-fallback'
height={size}
viewBox='0 0 384 512'
width={size}
xmlns='http://www.w3.org/2000/svg'
{...props}
>
<path
d='M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48z'
fill='#414D54'
/>
</svg>
);
Loading

0 comments on commit 1258e09

Please sign in to comment.