Skip to content

Commit eb3d500

Browse files
authored
feat: support mov file type rendering only in Safari browser (#1114)
Addresses https://sendbird.atlassian.net/browse/SBISSUE-16031?focusedCommentId=270601 Quoted a comment left by @jayden-lee-sb >Not supporting ‘MOV’: This is not a bug since we display ‘MOV’ as a normal file message exactly described in the changelog(v3.13.2) → But we need to consider supporting ‘ThumbnailMessage’ only for some browser environments like Safari where MOV can be displayed without any problem #### .mov file in Chrome browser <img width="500" alt="Screenshot 2024-05-29 at 5 24 43 PM" src="https://github.com/sendbird/sendbird-uikit-react/assets/10060731/07733c66-dd6f-4007-a127-c8d6853d8b5a"> #### .mov file in Safari browser <img width="500" alt="Screenshot 2024-05-29 at 5 25 43 PM" src="https://github.com/sendbird/sendbird-uikit-react/assets/10060731/529be97e-146f-489b-8625-3fdb8098a4a2">
1 parent 15eabe8 commit eb3d500

File tree

9 files changed

+26
-50
lines changed

9 files changed

+26
-50
lines changed

src/modules/GroupChannel/components/FileViewer/FileViewerView.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { FileViewerProps } from '.';
77
import type { CoreMessageType, SendableMessageType } from '../../../../utils';
88
import Avatar from '../../../../ui/Avatar';
99
import Icon, { IconColors, IconTypes } from '../../../../ui/Icon';
10-
import Label, { LabelColors, LabelTypography } from '../../../../ui/Label';
10+
import Label, { LabelColors, LabelTypography, LabelStringSet } from '../../../../ui/Label';
1111
import { isImage, isSupportedFileView, isVideo } from '../../../../utils';
1212
import { MODAL_ROOT } from '../../../../hooks/useModal';
1313
import useSendbirdStateContext from '../../../../hooks/useSendbirdStateContext';
@@ -135,7 +135,7 @@ export const FileViewerComponent = ({
135135
{!isSupportedFileView(type) && (
136136
<div className="sendbird-fileviewer__content__unsupported">
137137
<Label type={LabelTypography.H_1} color={LabelColors.ONBACKGROUND_1}>
138-
Unsupoprted message
138+
{LabelStringSet.UI__FILE_VIEWER__UNSUPPORT}
139139
</Label>
140140
</div>
141141
)}

src/modules/OpenChannel/components/OpenChannelMessage/utils.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { FileMessage } from '@sendbird/chat/message';
2-
import { isImage, isVideo } from '../../../../ui/FileViewer/types';
3-
import { CoreMessageType } from '../../../../utils';
2+
import { CoreMessageType, isImage, isVideo } from '../../../../utils';
43

54
export const MessageTypes = {
65
ADMIN: 'ADMIN',

src/ui/FileViewer/types.ts

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,7 @@
11
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types
22

33
// TODO: refactor this to -> as const pattern
4-
import { KeyboardEvent, MouseEvent } from 'react';
5-
6-
export type SupportedImageMimesType = 'image/jpeg' | 'image/jpg' | 'image/png' | 'image/gif' | 'image/svg+xml' | 'image/webp';
7-
export type SupportedVideoMimesType = 'video/mpeg' | 'video/ogg' | 'video/webm' | 'video/mp4';
8-
export type SupportedMimesType = SupportedImageMimesType | SupportedVideoMimesType;
9-
10-
const SUPPORTED_MIMES = {
11-
IMAGE: [
12-
'image/jpeg',
13-
'image/jpg',
14-
'image/png',
15-
'image/gif',
16-
'image/svg+xml',
17-
'image/webp',
18-
],
19-
VIDEO: [
20-
'video/mpeg',
21-
'video/ogg',
22-
'video/webm',
23-
'video/mp4',
24-
],
25-
};
26-
27-
export const isImage = (type: string): boolean => SUPPORTED_MIMES.IMAGE.indexOf(type) >= 0;
28-
export const isVideo = (type: string): boolean => SUPPORTED_MIMES.VIDEO.indexOf(type) >= 0;
29-
export const isGif = (type: string): boolean => type === 'image/gif';
30-
export const unSupported = (type: string): boolean => (
31-
!(
32-
isImage(type as SupportedImageMimesType)
33-
|| isVideo(type as SupportedVideoMimesType)
34-
)
35-
);
36-
37-
export default { ...SUPPORTED_MIMES };
4+
import { MouseEvent } from 'react';
385

396
export const ViewerTypes = {
407
SINGLE: 'SINGLE',

src/ui/MessageInput/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ import { tokenizeMessage } from '../../modules/Message/utils/tokens/tokenize';
1919
import { USER_MENTION_PREFIX } from '../../modules/Message/consts';
2020
import { TOKEN_TYPES } from '../../modules/Message/utils/tokens/types';
2121
import { checkIfFileUploadEnabled } from './messageInputUtils';
22-
import { classnames, isMobileIOS } from '../../utils/utils';
22+
import { classnames } from '../../utils/utils';
23+
import { isMobileIOS } from '../../utils/browser';
2324

2425
import { GroupChannel } from '@sendbird/chat/groupChannel';
2526
import { User } from '@sendbird/chat';

src/ui/ThumbnailMessageItemBody/__tests__/ThumbnailMessageItemBody.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { render, screen } from '@testing-library/react';
2+
import { render } from '@testing-library/react';
33

44
import ThumbnailMessageItemBody from "../index";
55

src/utils/__tests__/utils.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import {
66
isMultipleFilesMessage,
77
} from '../index';
88
import { AdminMessage, FileMessage, MultipleFilesMessage, UserMessage } from '@sendbird/chat/message';
9-
import { deleteNullish, isMobileIOS } from '../utils';
9+
import { deleteNullish } from '../utils';
10+
import { isMobileIOS } from '../browser';
1011

1112
describe('Global-utils: verify message type util functions', () => {
1213
it('should return true for each message', () => {

src/utils/browser.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const isIOS = (userAgent: string) => /iPhone|iPad|iPod/i.test(userAgent);
2+
const isWebkit = (userAgent: string) => /WebKit/i.test(userAgent);
3+
const isChrome = (userAgent: string) => /Chrome/i.test(userAgent);
4+
export const isSafari = (userAgent: string) => !isChrome(userAgent) && /Safari/i.test(userAgent);
5+
export const isMobileIOS = (userAgent: string) => {
6+
return isIOS(userAgent) && (isWebkit(userAgent) || isSafari(userAgent));
7+
};

src/utils/index.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ import {
1111
UserMessage,
1212
} from '@sendbird/chat/message';
1313
import { OpenChannel, SendbirdOpenChat } from '@sendbird/chat/openChannel';
14+
import { SendableMessage } from '@sendbird/chat/lib/__definition';
1415

1516
import { getOutgoingMessageState, OutgoingMessageStates } from './exports/getOutgoingMessageState';
1617
import { MessageContentMiddleContainerType, Nullable } from '../types';
18+
import { isSafari } from './browser';
1719
import { match } from 'ts-pattern';
18-
import { SendableMessage } from '@sendbird/chat/lib/__definition';
1920

2021
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types
2122
export const SUPPORTED_MIMES = {
@@ -190,8 +191,15 @@ export const isTextuallyNull = (text: string): boolean => {
190191
return false;
191192
};
192193

194+
export const isMOVType = (type: string): boolean => type === 'video/quicktime';
195+
/**
196+
* @link: https://sendbird.atlassian.net/browse/SBISSUE-16031?focusedCommentId=270601
197+
* We limitedly support .mov file type for ThumbnailMessage only in Safari browser.
198+
* */
199+
export const isSupportedVideoFileTypeInSafari = (type: string): boolean => isSafari(navigator.userAgent) && isMOVType(type);
193200
export const isImage = (type: string): boolean => SUPPORTED_MIMES.IMAGE.indexOf(type) >= 0;
194-
export const isVideo = (type: string): boolean => SUPPORTED_MIMES.VIDEO.indexOf(type) >= 0;
201+
export const isVideo = (type: string): boolean => SUPPORTED_MIMES.VIDEO.indexOf(type) >= 0
202+
|| isSupportedVideoFileTypeInSafari(type);
195203
export const isGif = (type: string): boolean => type === 'image/gif';
196204
export const isSupportedFileView = (type: string): boolean => isImage(type) || isVideo(type);
197205
export const isAudio = (type: string): boolean => SUPPORTED_MIMES.AUDIO.indexOf(type) >= 0;

src/utils/utils.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,6 @@ export const noop = () => {
66
export const getSenderProfileUrl = (message: SendableMessageType) => message.sender && message.sender.profileUrl;
77
export const getSenderName = (message: SendableMessageType) => message.sender && (message.sender.friendName || message.sender.nickname || message.sender.userId);
88
export const isAboutSame = (a: number, b: number, px: number) => Math.abs(a - b) <= px;
9-
export const isMobileIOS = (userAgent: string) => {
10-
const isIOS = /iPhone|iPad|iPod/i.test(userAgent);
11-
const isWebkit = /WebKit/i.test(userAgent);
12-
const isSafari = /Safari/i.test(userAgent);
13-
14-
return isIOS && (isWebkit || isSafari);
15-
};
169

1710
export const deleteNullish = <T>(obj: T): T => {
1811
const cleaned = {} as T;

0 commit comments

Comments
 (0)