Use same lock values as mobile clients
[ProtonMail-WebClient.git] / packages / shared / lib / helpers / mimetype.ts
blob127d2123ff0279dfce5a7ca6ef71061b521c9c1b
1 import { getBrowser, getOS, isAndroid, isDesktop, isIos, isMobile } from '@proton/shared/lib/helpers/browser';
3 import { MIME_TYPES } from '../constants';
4 import { SupportedMimeTypes, SupportedProtonDocsMimeTypes } from '../drive/constants';
5 import { Version } from './version';
7 const isWebpSupported = () => {
8     const { name, version } = getBrowser();
10     if (name === 'Safari') {
11         /*
12          * The support for WebP image format became available in Safari 14.
13          * It is not possible to support webp images in older Safari versions.
14          * https://developer.apple.com/documentation/safari-release-notes/safari-14-release-notes
15          */
16         return Number(version?.split('.')[0]) >= 14;
17     }
19     return true;
22 const isAVIFSupported = () => {
23     /*
24      * The support for AVIF image format did reach baseline in early 2024.
25      * Since it's still early and customers might not be on latest browser versions yet,
26      * we're taking a safe approach allowing browsers and version for some time before removing this support check.
27      * There is no clean way to detect AVIF support (eg: https://avif.io/blog/tutorials/css/#avifsupportdetectionscript) so we're using user-agent detection.
28      * https://caniuse.com/?search=AVIF
29      */
30     let isSupported = false;
31     const { name, version } = getBrowser();
33     if (version) {
34         const currentVersion = new Version(version);
36         if (
37             isDesktop() &&
38             ((name === 'Chrome' && currentVersion.isGreaterThanOrEqual('85')) ||
39                 (name === 'Edge' && currentVersion.isGreaterThanOrEqual('121')) ||
40                 (name === 'Safari' && currentVersion.isGreaterThanOrEqual('16.4')) ||
41                 (name === 'Firefox' && currentVersion.isGreaterThanOrEqual('16.4')) ||
42                 (name === 'Opera' && currentVersion.isGreaterThanOrEqual('71')))
43         ) {
44             isSupported = true;
45         }
47         if (
48             isMobile() &&
49             ((isAndroid() &&
50                 (name === 'Chrome' || name === 'Chromium') &&
51                 currentVersion.isGreaterThanOrEqual('123')) ||
52                 (isIos() && name === 'Safari' && currentVersion.isGreaterThanOrEqual('16.4')))
53         ) {
54             isSupported = true;
55         }
56     }
58     return isSupported;
61 const isHEICSupported = () => {
62     const os = getOS();
63     const { name, version } = getBrowser();
64     return (
65         ['mac os', 'ios'].includes(os.name.toLowerCase()) &&
66         ['Safari', 'Mobile Safari'].includes(name || '') &&
67         version &&
68         new Version(version).isGreaterThanOrEqual('17')
69     );
72 const isJXLSupported = () => {
73     const os = getOS();
74     const { name, version } = getBrowser();
75     return (
76         ['mac os', 'ios'].includes(os.name.toLowerCase()) &&
77         ['Safari', 'Mobile Safari'].includes(name || '') &&
78         version &&
79         new Version(version).isGreaterThanOrEqual('17')
80     );
83 export const isImage = (mimeType: string) => mimeType.startsWith('image/');
85 export const isExcel = (mimeType: string) => mimeType.startsWith('application/vnd.ms-excel');
87 export const isWordDocument = (mimeType: string) => mimeType === SupportedMimeTypes.docx;
89 export const isFont = (mimeType: string) => mimeType.startsWith('font/');
91 export const isSupportedImage = (mimeType: string) =>
92     [
93         SupportedMimeTypes.apng,
94         SupportedMimeTypes.bmp,
95         SupportedMimeTypes.gif,
96         SupportedMimeTypes.ico,
97         SupportedMimeTypes.vdnMicrosoftIcon,
98         SupportedMimeTypes.jpg,
99         SupportedMimeTypes.png,
100         SupportedMimeTypes.svg,
101         isWebpSupported() && SupportedMimeTypes.webp,
102         isAVIFSupported() && SupportedMimeTypes.avif,
103         isHEICSupported() && SupportedMimeTypes.heic,
104         isJXLSupported() && SupportedMimeTypes.jxl,
105     ]
106         .filter(Boolean)
107         .includes(mimeType as SupportedMimeTypes);
109 export const isSVG = (mimeType: string) => mimeType === SupportedMimeTypes.svg;
111 export const isICS = (mimeType: string) =>
112     mimeType.startsWith(MIME_TYPES.ICS) || mimeType.includes(MIME_TYPES.APPLICATION_ICS);
114 export const isSupportedText = (mimeType: string) =>
115     mimeType.startsWith('text/') ||
116     [
117         'application/json',
118         'application/javascript',
119         'application/typescript',
120         'application/x-tex',
121         'application/x-csh',
122         'application/x-sh',
123         'application/x-httpd-php',
124         'application/xhtml+xml',
125     ].includes(mimeType);
126 export const isVideo = (mimeType: string) => mimeType.startsWith('video/');
127 export const isAudio = (mimeType: string) => mimeType.startsWith('audio/');
128 export const isPDF = (mimeType: string) =>
129     mimeType === SupportedMimeTypes.pdf ||
130     // Some e-mail clients will use this legacy value
131     mimeType === 'application/x-pdf';
134  * A helper function to determine if a mimetype can be converted by Proton Docs.
135  */
136 export const isProtonDocsConvertible = (mimeType: string) =>
137     mimeType === SupportedProtonDocsMimeTypes.docx ||
138     mimeType === SupportedProtonDocsMimeTypes.txt ||
139     mimeType === SupportedProtonDocsMimeTypes.md ||
140     mimeType === SupportedProtonDocsMimeTypes.html;
142 export const PROTON_DOC_MIMETYPE = 'application/vnd.proton.doc';
143 export const isProtonDocument = (mimeType: string) => mimeType === PROTON_DOC_MIMETYPE;