@@ -141,7 +118,7 @@ exports[`renders Default without crashing 1`] = `
- Send
+ Update
diff --git a/apps/meteor/client/views/room/webdav/WebdavFilePickerModal/WebdavFilePickerModal.tsx b/apps/meteor/client/views/room/webdav/WebdavFilePickerModal/WebdavFilePickerModal.tsx
index 51ca961b6f41c..2483519ec2608 100644
--- a/apps/meteor/client/views/room/webdav/WebdavFilePickerModal/WebdavFilePickerModal.tsx
+++ b/apps/meteor/client/views/room/webdav/WebdavFilePickerModal/WebdavFilePickerModal.tsx
@@ -3,7 +3,7 @@ import type { SelectOption } from '@rocket.chat/fuselage';
import { Modal, Box, IconButton, Select, ModalHeader, ModalTitle, ModalClose, ModalContent, ModalFooter } from '@rocket.chat/fuselage';
import { useEffectEvent, useDebouncedValue } from '@rocket.chat/fuselage-hooks';
import { useSort } from '@rocket.chat/ui-client';
-import { useMethod, useToastMessageDispatch, useTranslation, useSetModal } from '@rocket.chat/ui-contexts';
+import { useMethod, useToastMessageDispatch, useTranslation } from '@rocket.chat/ui-contexts';
import type { ReactElement, MouseEvent } from 'react';
import { useState, useEffect, useCallback } from 'react';
@@ -11,21 +11,18 @@ import FilePickerBreadcrumbs from './FilePickerBreadcrumbs';
import WebdavFilePickerGrid from './WebdavFilePickerGrid';
import WebdavFilePickerTable from './WebdavFilePickerTable';
import { sortWebdavNodes } from './lib/sortWebdavNodes';
-import { fileUploadIsValidContentType } from '../../../../../app/utils/client';
import FilterByText from '../../../../components/FilterByText';
-import FileUploadModal from '../../modals/FileUploadModal';
export type WebdavSortOptions = 'name' | 'size' | 'dataModified';
type WebdavFilePickerModalProps = {
- onUpload: (file: File, description?: string) => Promise;
+ onUpload: (file: File) => Promise;
onClose: () => void;
account: IWebdavAccountIntegration;
};
const WebdavFilePickerModal = ({ onUpload, onClose, account }: WebdavFilePickerModalProps): ReactElement => {
const t = useTranslation();
- const setModal = useSetModal();
const getWebdavFilePreview = useMethod('getWebdavFilePreview');
const getWebdavFileList = useMethod('getWebdavFileList');
const getFileFromWebdav = useMethod('getFileFromWebdav');
@@ -131,9 +128,9 @@ const WebdavFilePickerModal = ({ onUpload, onClose, account }: WebdavFilePickerM
const handleUpload = async (webdavNode: IWebdavNode): Promise => {
setIsLoading(true);
- const uploadFile = async (file: File, description?: string): Promise => {
+ const uploadFile = async (file: File): Promise => {
try {
- await onUpload?.(file, description);
+ await onUpload?.(file);
} catch (error) {
return dispatchToastMessage({ type: 'error', message: error });
} finally {
@@ -147,15 +144,7 @@ const WebdavFilePickerModal = ({ onUpload, onClose, account }: WebdavFilePickerM
const blob = new Blob([data]);
const file = new File([blob], webdavNode.basename, { type: webdavNode.mime });
- setModal(
- => uploadFile(file, description)}
- file={file}
- onClose={(): void => setModal(null)}
- invalidContentType={Boolean(file.type && !fileUploadIsValidContentType(file.type))}
- />,
- );
+ await uploadFile(file);
} catch (error) {
return dispatchToastMessage({ type: 'error', message: error });
}
diff --git a/apps/meteor/lib/constants.ts b/apps/meteor/lib/constants.ts
index 61b66421ce446..4c4b572ca210f 100644
--- a/apps/meteor/lib/constants.ts
+++ b/apps/meteor/lib/constants.ts
@@ -1 +1,2 @@
export const NOTIFICATION_ATTACHMENT_COLOR = '#FD745E';
+export const MAX_MULTIPLE_UPLOADED_FILES = 10;
diff --git a/apps/meteor/licenses/NotoSans-OFL.txt b/apps/meteor/licenses/NotoSans-OFL.txt
new file mode 100644
index 0000000000000..6843f31878c99
--- /dev/null
+++ b/apps/meteor/licenses/NotoSans-OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2022 The Noto Project Authors (https://github.com/notofonts/latin-greek-cyrillic)
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/apps/meteor/licenses/NotoSansArabic-OFL.txt b/apps/meteor/licenses/NotoSansArabic-OFL.txt
new file mode 100644
index 0000000000000..14c589f638450
--- /dev/null
+++ b/apps/meteor/licenses/NotoSansArabic-OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2022 The Noto Project Authors (https://github.com/notofonts/arabic)
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/apps/meteor/licenses/NotoSansBengali-OFL.txt b/apps/meteor/licenses/NotoSansBengali-OFL.txt
new file mode 100644
index 0000000000000..d11cac69316ec
--- /dev/null
+++ b/apps/meteor/licenses/NotoSansBengali-OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2022 The Noto Project Authors (https://github.com/notofonts/bengali)
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/apps/meteor/licenses/NotoSansDevanagari-OFL.txt b/apps/meteor/licenses/NotoSansDevanagari-OFL.txt
new file mode 100644
index 0000000000000..cd2cc5c94b415
--- /dev/null
+++ b/apps/meteor/licenses/NotoSansDevanagari-OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2022 The Noto Project Authors (https://github.com/notofonts/devanagari)
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/apps/meteor/licenses/NotoSansGeorgian-OFL.txt b/apps/meteor/licenses/NotoSansGeorgian-OFL.txt
new file mode 100644
index 0000000000000..437070a9ee723
--- /dev/null
+++ b/apps/meteor/licenses/NotoSansGeorgian-OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2022 The Noto Project Authors (https://github.com/notofonts/georgian)
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/apps/meteor/licenses/NotoSansHK-OFL.txt b/apps/meteor/licenses/NotoSansHK-OFL.txt
new file mode 100644
index 0000000000000..1c9f43281b8f2
--- /dev/null
+++ b/apps/meteor/licenses/NotoSansHK-OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/apps/meteor/licenses/NotoSansHebrew-OFL.txt b/apps/meteor/licenses/NotoSansHebrew-OFL.txt
new file mode 100644
index 0000000000000..56662b6243717
--- /dev/null
+++ b/apps/meteor/licenses/NotoSansHebrew-OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2022 The Noto Project Authors (https://github.com/notofonts/hebrew)
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/apps/meteor/licenses/NotoSansJP-OFL.txt b/apps/meteor/licenses/NotoSansJP-OFL.txt
new file mode 100644
index 0000000000000..1c9f43281b8f2
--- /dev/null
+++ b/apps/meteor/licenses/NotoSansJP-OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/apps/meteor/licenses/NotoSansKR-OFL.txt b/apps/meteor/licenses/NotoSansKR-OFL.txt
new file mode 100644
index 0000000000000..1c9f43281b8f2
--- /dev/null
+++ b/apps/meteor/licenses/NotoSansKR-OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/apps/meteor/licenses/NotoSansLao-OFL.txt b/apps/meteor/licenses/NotoSansLao-OFL.txt
new file mode 100644
index 0000000000000..483c04d1b6a1c
--- /dev/null
+++ b/apps/meteor/licenses/NotoSansLao-OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2022 The Noto Project Authors (https://github.com/notofonts/lao)
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/apps/meteor/licenses/NotoSansSC-OFL.txt b/apps/meteor/licenses/NotoSansSC-OFL.txt
new file mode 100644
index 0000000000000..1c9f43281b8f2
--- /dev/null
+++ b/apps/meteor/licenses/NotoSansSC-OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/apps/meteor/licenses/NotoSansSinhala-OFL.txt b/apps/meteor/licenses/NotoSansSinhala-OFL.txt
new file mode 100644
index 0000000000000..4e06fdff46ede
--- /dev/null
+++ b/apps/meteor/licenses/NotoSansSinhala-OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2022 The Noto Project Authors (https://github.com/notofonts/sinhala)
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/apps/meteor/licenses/NotoSansTC-OFL.txt b/apps/meteor/licenses/NotoSansTC-OFL.txt
new file mode 100644
index 0000000000000..1c9f43281b8f2
--- /dev/null
+++ b/apps/meteor/licenses/NotoSansTC-OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/apps/meteor/licenses/NotoSansTamil-OFL.txt b/apps/meteor/licenses/NotoSansTamil-OFL.txt
new file mode 100644
index 0000000000000..677d559b94ba7
--- /dev/null
+++ b/apps/meteor/licenses/NotoSansTamil-OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2022 The Noto Project Authors (https://github.com/notofonts/tamil)
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/apps/meteor/licenses/NotoSansThai-OFL.txt b/apps/meteor/licenses/NotoSansThai-OFL.txt
new file mode 100644
index 0000000000000..7fa8dcb08ce4d
--- /dev/null
+++ b/apps/meteor/licenses/NotoSansThai-OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2022 The Noto Project Authors (https://github.com/notofonts/thai)
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/apps/meteor/licenses/THIRD-PARTY-LICENSES.md b/apps/meteor/licenses/THIRD-PARTY-LICENSES.md
new file mode 100644
index 0000000000000..b17499b50c2ca
--- /dev/null
+++ b/apps/meteor/licenses/THIRD-PARTY-LICENSES.md
@@ -0,0 +1,36 @@
+# Third-Party Licenses
+
+This document contains the licenses for third-party software and assets included in or distributed with this project.
+
+## Fonts
+
+### Noto Sans Fonts
+
+- **Project**: Noto Sans (variable fonts, multiple scripts)
+- **Source**: https://github.com/google/fonts/tree/main/ofl
+- **License**: SIL Open Font License 1.1
+- **Copyright**: The Noto Project Authors; Adobe (Noto Sans JP, KR, SC, TC, HK)
+
+| Font | Copyright | License file |
+|------|-----------|--------------|
+| Noto Sans | Copyright 2022 The Noto Project Authors (https://github.com/notofonts/latin-greek-cyrillic) | [NotoSans-OFL.txt](./NotoSans-OFL.txt) |
+| Noto Sans Arabic | Copyright 2022 The Noto Project Authors (https://github.com/notofonts/arabic) | [NotoSansArabic-OFL.txt](./NotoSansArabic-OFL.txt) |
+| Noto Sans Bengali | Copyright 2022 The Noto Project Authors (https://github.com/notofonts/bengali) | [NotoSansBengali-OFL.txt](./NotoSansBengali-OFL.txt) |
+| Noto Sans Devanagari | Copyright 2022 The Noto Project Authors (https://github.com/notofonts/devanagari) | [NotoSansDevanagari-OFL.txt](./NotoSansDevanagari-OFL.txt) |
+| Noto Sans Georgian | Copyright 2022 The Noto Project Authors (https://github.com/notofonts/georgian) | [NotoSansGeorgian-OFL.txt](./NotoSansGeorgian-OFL.txt) |
+| Noto Sans Hebrew | Copyright 2022 The Noto Project Authors (https://github.com/notofonts/hebrew) | [NotoSansHebrew-OFL.txt](./NotoSansHebrew-OFL.txt) |
+| Noto Sans HK | Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source' | [NotoSansHK-OFL.txt](./NotoSansHK-OFL.txt) |
+| Noto Sans JP | Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source' | [NotoSansJP-OFL.txt](./NotoSansJP-OFL.txt) |
+| Noto Sans KR | Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source' | [NotoSansKR-OFL.txt](./NotoSansKR-OFL.txt) |
+| Noto Sans Lao | Copyright 2022 The Noto Project Authors (https://github.com/notofonts/lao) | [NotoSansLao-OFL.txt](./NotoSansLao-OFL.txt) |
+| Noto Sans SC | Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source' | [NotoSansSC-OFL.txt](./NotoSansSC-OFL.txt) |
+| Noto Sans Sinhala | Copyright 2022 The Noto Project Authors (https://github.com/notofonts/sinhala) | [NotoSansSinhala-OFL.txt](./NotoSansSinhala-OFL.txt) |
+| Noto Sans Tamil | Copyright 2022 The Noto Project Authors (https://github.com/notofonts/tamil) | [NotoSansTamil-OFL.txt](./NotoSansTamil-OFL.txt) |
+| Noto Sans TC | Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source' | [NotoSansTC-OFL.txt](./NotoSansTC-OFL.txt) |
+| Noto Sans Thai | Copyright 2022 The Noto Project Authors (https://github.com/notofonts/thai) | [NotoSansThai-OFL.txt](./NotoSansThai-OFL.txt) |
+
+The Noto Sans font files are used for PDF export and are licensed under the SIL Open Font License 1.1. The full license text for each variant can be found in the `licenses` folder (e.g. `NotoSans-OFL.txt`, `NotoSansHebrew-OFL.txt`) and at https://scripts.sil.org/OFL
+
+#### License Summary
+
+The SIL Open Font License allows the fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works.
diff --git a/apps/meteor/package.json b/apps/meteor/package.json
index e0181a8d66ca1..e689325b89394 100644
--- a/apps/meteor/package.json
+++ b/apps/meteor/package.json
@@ -87,7 +87,7 @@
"@opentelemetry/sdk-node": "^0.54.2",
"@parse/node-apn": "^7.0.1",
"@react-aria/toolbar": "^3.0.0-nightly.5042",
- "@react-pdf/renderer": "^3.4.5",
+ "@react-pdf/renderer": "^4.3.2",
"@rocket.chat/abac": "workspace:^",
"@rocket.chat/account-utils": "workspace:^",
"@rocket.chat/agenda": "workspace:^",
@@ -305,6 +305,7 @@
"xml-encryption": "~3.1.0",
"xml2js": "~0.6.2",
"yaqrcode": "^0.2.1",
+ "yoga-layout": "patch:yoga-layout@npm%3A3.2.1#~/.yarn/patches/yoga-layout-npm-3.2.1-51ec934670.patch",
"zod": "~4.3.6",
"zustand": "~5.0.10"
},
diff --git a/apps/meteor/public/fonts/NotoSans-Italic-VariableFont_wdth,wght.ttf b/apps/meteor/public/fonts/NotoSans-Italic-VariableFont_wdth,wght.ttf
new file mode 100644
index 0000000000000..6245ba014b1f2
Binary files /dev/null and b/apps/meteor/public/fonts/NotoSans-Italic-VariableFont_wdth,wght.ttf differ
diff --git a/apps/meteor/public/fonts/NotoSans-Regular.ttf b/apps/meteor/public/fonts/NotoSans-Regular.ttf
new file mode 100644
index 0000000000000..7da1a0fad8c71
Binary files /dev/null and b/apps/meteor/public/fonts/NotoSans-Regular.ttf differ
diff --git a/apps/meteor/public/fonts/NotoSansArabic-Regular.ttf b/apps/meteor/public/fonts/NotoSansArabic-Regular.ttf
new file mode 100644
index 0000000000000..b3b82dcc6e513
Binary files /dev/null and b/apps/meteor/public/fonts/NotoSansArabic-Regular.ttf differ
diff --git a/apps/meteor/public/fonts/NotoSansBengali-Regular.ttf b/apps/meteor/public/fonts/NotoSansBengali-Regular.ttf
new file mode 100644
index 0000000000000..3bc7589601e3e
Binary files /dev/null and b/apps/meteor/public/fonts/NotoSansBengali-Regular.ttf differ
diff --git a/apps/meteor/public/fonts/NotoSansDevanagari-Regular.ttf b/apps/meteor/public/fonts/NotoSansDevanagari-Regular.ttf
new file mode 100644
index 0000000000000..07480c02e0864
Binary files /dev/null and b/apps/meteor/public/fonts/NotoSansDevanagari-Regular.ttf differ
diff --git a/apps/meteor/public/fonts/NotoSansGeorgian-Regular.ttf b/apps/meteor/public/fonts/NotoSansGeorgian-Regular.ttf
new file mode 100644
index 0000000000000..8f3e75d2154cc
Binary files /dev/null and b/apps/meteor/public/fonts/NotoSansGeorgian-Regular.ttf differ
diff --git a/apps/meteor/public/fonts/NotoSansHK-Regular.ttf b/apps/meteor/public/fonts/NotoSansHK-Regular.ttf
new file mode 100644
index 0000000000000..3405514dd79cc
Binary files /dev/null and b/apps/meteor/public/fonts/NotoSansHK-Regular.ttf differ
diff --git a/apps/meteor/public/fonts/NotoSansHebrew-Regular.ttf b/apps/meteor/public/fonts/NotoSansHebrew-Regular.ttf
new file mode 100644
index 0000000000000..f7956338f8a40
Binary files /dev/null and b/apps/meteor/public/fonts/NotoSansHebrew-Regular.ttf differ
diff --git a/apps/meteor/public/fonts/NotoSansJP-Regular.ttf b/apps/meteor/public/fonts/NotoSansJP-Regular.ttf
new file mode 100644
index 0000000000000..6c730cd848ecc
Binary files /dev/null and b/apps/meteor/public/fonts/NotoSansJP-Regular.ttf differ
diff --git a/apps/meteor/public/fonts/NotoSansKR-Regular.ttf b/apps/meteor/public/fonts/NotoSansKR-Regular.ttf
new file mode 100644
index 0000000000000..36e634d21df4e
Binary files /dev/null and b/apps/meteor/public/fonts/NotoSansKR-Regular.ttf differ
diff --git a/apps/meteor/public/fonts/NotoSansLao-Regular.ttf b/apps/meteor/public/fonts/NotoSansLao-Regular.ttf
new file mode 100644
index 0000000000000..7485ca10b235b
Binary files /dev/null and b/apps/meteor/public/fonts/NotoSansLao-Regular.ttf differ
diff --git a/apps/meteor/public/fonts/NotoSansSC-Regular.ttf b/apps/meteor/public/fonts/NotoSansSC-Regular.ttf
new file mode 100644
index 0000000000000..6043afcf4cbfd
Binary files /dev/null and b/apps/meteor/public/fonts/NotoSansSC-Regular.ttf differ
diff --git a/apps/meteor/public/fonts/NotoSansSinhala-Regular.ttf b/apps/meteor/public/fonts/NotoSansSinhala-Regular.ttf
new file mode 100644
index 0000000000000..ee139658ff0c8
Binary files /dev/null and b/apps/meteor/public/fonts/NotoSansSinhala-Regular.ttf differ
diff --git a/apps/meteor/public/fonts/NotoSansTC-Regular.ttf b/apps/meteor/public/fonts/NotoSansTC-Regular.ttf
new file mode 100644
index 0000000000000..2defdb937df66
Binary files /dev/null and b/apps/meteor/public/fonts/NotoSansTC-Regular.ttf differ
diff --git a/apps/meteor/public/fonts/NotoSansTamil-Regular.ttf b/apps/meteor/public/fonts/NotoSansTamil-Regular.ttf
new file mode 100644
index 0000000000000..0400d8f49bee0
Binary files /dev/null and b/apps/meteor/public/fonts/NotoSansTamil-Regular.ttf differ
diff --git a/apps/meteor/public/fonts/NotoSansThai-Regular.ttf b/apps/meteor/public/fonts/NotoSansThai-Regular.ttf
new file mode 100644
index 0000000000000..f17b1341f1cda
Binary files /dev/null and b/apps/meteor/public/fonts/NotoSansThai-Regular.ttf differ
diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-encryption-decryption.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-encryption-decryption.spec.ts
index 330b306cb4a86..7d522e47c3c2e 100644
--- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-encryption-decryption.spec.ts
+++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-encryption-decryption.spec.ts
@@ -95,14 +95,18 @@ test.describe('E2EE Encryption and Decryption - Basic Features', () => {
await test.step('upload the file with encryption', async () => {
// Upload a file
- await encryptedRoomPage.dragAndDropTxtFile();
+ await encryptedRoomPage.sendFileMessage('any_file.txt');
+
+ // Update file name and send
+ await encryptedRoomPage.composer.getFileByName('any_file.txt').click();
await fileUploadModal.setName(fileName);
- await fileUploadModal.setDescription(fileDescription);
- await fileUploadModal.send();
+ await fileUploadModal.update();
+ await expect(encryptedRoomPage.composer.getFileByName(fileName)).toBeVisible();
- // Check the file upload
+ await encryptedRoomPage.composer.inputMessage.fill(fileDescription);
+ await encryptedRoomPage.composer.btnSend.click();
await expect(encryptedRoomPage.lastMessage.encryptedIcon).toBeVisible();
- await expect(encryptedRoomPage.lastMessage.getFileUploadByName(fileName)).toBeVisible();
+ await expect(encryptedRoomPage.lastMessage.getFileUploadByName(fileName)).toContainText(fileName);
await expect(encryptedRoomPage.lastMessage.body).toHaveText(fileDescription);
});
@@ -113,12 +117,19 @@ test.describe('E2EE Encryption and Decryption - Basic Features', () => {
await test.step('upload the file without encryption', async () => {
await encryptedRoomPage.dragAndDropTxtFile();
- await fileUploadModal.setName(fileName);
- await fileUploadModal.setDescription(fileDescription);
- await fileUploadModal.send();
+ // Update file name and send
+ await expect(async () => {
+ await encryptedRoomPage.composer.getFileByName('any_file.txt').click();
+ await fileUploadModal.setName(fileName);
+ await fileUploadModal.update();
+ await expect(encryptedRoomPage.composer.getFileByName(fileName)).toBeVisible();
+ }).toPass();
+
+ await encryptedRoomPage.composer.inputMessage.fill(fileDescription);
+ await encryptedRoomPage.composer.btnSend.click();
await expect(encryptedRoomPage.lastMessage.encryptedIcon).not.toBeVisible();
- await expect(encryptedRoomPage.lastMessage.getFileUploadByName(fileName)).toBeVisible();
+ await expect(encryptedRoomPage.lastMessage.getFileUploadByName(fileName)).toContainText(fileName);
await expect(encryptedRoomPage.lastMessage.body).toHaveText(fileDescription);
});
@@ -144,7 +155,7 @@ test.describe('E2EE Encryption and Decryption - Basic Features', () => {
await expect(encryptedRoomPage.lastNthMessage(1).encryptedIcon).toBeVisible();
await expect(encryptedRoomPage.lastMessage.encryptedIcon).not.toBeVisible();
- await expect(encryptedRoomPage.lastMessage.getFileUploadByName(fileName)).toBeVisible();
+ await expect(encryptedRoomPage.lastMessage.getFileUploadByName(fileName)).toContainText(fileName);
await expect(encryptedRoomPage.lastMessage.body).toHaveText(fileDescription);
});
diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-file-encryption.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-file-encryption.spec.ts
index da41810380978..9ab5127448a05 100644
--- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-file-encryption.spec.ts
+++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-file-encryption.spec.ts
@@ -14,6 +14,8 @@ const settingsList = [
const originalSettings = preserveSettings(settingsList);
+const TEST_FILE_TXT = 'any_file.txt';
+
test.use({ storageState: Users.userE2EE.state });
test.describe('E2EE File Encryption', () => {
@@ -54,16 +56,21 @@ test.describe('E2EE File Encryption', () => {
expect((await api.post('/groups.delete', { roomId: encryptedRoomId })).status()).toBe(200);
});
- test('File and description encryption and editing the description', async ({ page }) => {
- await test.step('send a file in channel', async () => {
- await poHomeChannel.content.dragAndDropTxtFile();
- await poHomeChannel.content.descriptionInput.fill('any_description');
- await poHomeChannel.content.fileNameInput.fill('any_file1.txt');
- await poHomeChannel.content.btnModalConfirm.click();
+ test('should edit encrypted message with file', async ({ page }) => {
+ const updatedFileName = `edited_${TEST_FILE_TXT}`;
+ await test.step('send a file in channel and edit it', async () => {
+ await poHomeChannel.content.sendFileMessage(TEST_FILE_TXT);
+ await poHomeChannel.composer.getFileByName(TEST_FILE_TXT).click();
+ await poHomeChannel.content.inputFileUploadName.fill(updatedFileName);
+ await poHomeChannel.content.btnUpdateFileUpload.click();
+ await expect(poHomeChannel.composer.getFileByName(updatedFileName)).toBeVisible();
+
+ await poHomeChannel.composer.inputMessage.fill('any_description');
+ await poHomeChannel.composer.btnSend.click();
await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible();
await expect(poHomeChannel.content.getFileDescription).toHaveText('any_description');
- await expect(poHomeChannel.content.getLastMessageByFileName('any_file1.txt')).toBeVisible();
+ await expect(poHomeChannel.content.getLastMessageByFileName(updatedFileName)).toContainText(updatedFileName);
});
await test.step('edit the description', async () => {
@@ -76,28 +83,31 @@ test.describe('E2EE File Encryption', () => {
await page.keyboard.press('Enter');
await expect(poHomeChannel.content.getFileDescription).toHaveText('edited any_description');
+ await expect(poHomeChannel.content.lastUserMessage.getByRole('link').getByText(updatedFileName)).toBeVisible();
});
await test.step('delete the file from files list', async () => {
await poHomeChannel.roomToolbar.openMoreOptions();
await poHomeChannel.roomToolbar.menuItemFiles.click();
- await poHomeChannel.tabs.files.deleteFile('any_file1.txt');
+ await poHomeChannel.tabs.files.deleteFile(updatedFileName);
- await expect(poHomeChannel.tabs.files.getFileByName('any_file1.txt')).toHaveCount(0);
- await expect(poHomeChannel.content.lastUserMessage).not.toBeVisible();
+ await expect(poHomeChannel.tabs.files.getFileByName(updatedFileName)).toHaveCount(0);
+ await expect(poHomeChannel.content.lastUserMessage.getByRole('link').getByText(updatedFileName)).not.toBeVisible();
});
});
test('File encryption with whitelisted and blacklisted media types', async ({ api }) => {
await test.step('send a text file in channel', async () => {
- await poHomeChannel.content.dragAndDropTxtFile();
- await poHomeChannel.content.descriptionInput.fill('message 1');
- await poHomeChannel.content.fileNameInput.fill('any_file1.txt');
- await poHomeChannel.content.btnModalConfirm.click();
+ const updatedFileName = `edited_${TEST_FILE_TXT}`;
+ await poHomeChannel.content.sendFileMessage(TEST_FILE_TXT);
+ await poHomeChannel.composer.getFileByName(TEST_FILE_TXT).click();
+ await poHomeChannel.content.inputFileUploadName.fill(updatedFileName);
+ await poHomeChannel.content.btnUpdateFileUpload.click();
+ await poHomeChannel.composer.btnSend.click();
await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible();
- await expect(poHomeChannel.content.getFileDescription).toHaveText('message 1');
- await expect(poHomeChannel.content.getLastMessageByFileName('any_file1.txt')).toBeVisible();
+ await expect(poHomeChannel.content.getFileDescription).not.toBeVisible();
+ await expect(poHomeChannel.content.getLastMessageByFileName(updatedFileName)).toContainText(updatedFileName);
});
await test.step('set whitelisted media type setting', async () => {
@@ -105,10 +115,12 @@ test.describe('E2EE File Encryption', () => {
});
await test.step('send text file again with whitelist setting set', async () => {
- await poHomeChannel.content.dragAndDropTxtFile();
- await poHomeChannel.content.descriptionInput.fill('message 2');
- await poHomeChannel.content.fileNameInput.fill('any_file2.txt');
- await poHomeChannel.content.btnModalConfirm.click();
+ await poHomeChannel.content.sendFileMessage(TEST_FILE_TXT);
+ await poHomeChannel.composer.inputMessage.fill('message 2');
+ await poHomeChannel.composer.getFileByName(TEST_FILE_TXT).click();
+ await poHomeChannel.content.inputFileUploadName.fill('any_file2.txt');
+ await poHomeChannel.content.btnUpdateFileUpload.click();
+ await poHomeChannel.composer.btnSend.click();
await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible();
await expect(poHomeChannel.content.getFileDescription).toHaveText('message 2');
@@ -121,13 +133,10 @@ test.describe('E2EE File Encryption', () => {
await test.step('send text file again with blacklisted setting set, file upload should fail', async () => {
await poHomeChannel.content.dragAndDropTxtFile();
- await poHomeChannel.content.descriptionInput.fill('message 3');
- await poHomeChannel.content.fileNameInput.fill('any_file3.txt');
- await poHomeChannel.content.btnModalConfirm.click();
+ const composerFiles = await poHomeChannel.composer.getFileByName(TEST_FILE_TXT).all();
+ await Promise.all(composerFiles.map((file) => expect(file).toHaveAttribute('readonly')));
await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible();
- await expect(poHomeChannel.content.getFileDescription).toHaveText('message 2');
- await expect(poHomeChannel.content.getLastMessageByFileName('any_file2.txt')).toBeVisible();
});
});
@@ -152,13 +161,15 @@ test.describe('E2EE File Encryption', () => {
await test.step('send a text file in channel, file should not be encrypted', async () => {
await poHomeChannel.content.dragAndDropTxtFile();
- await poHomeChannel.content.descriptionInput.fill('any_description');
- await poHomeChannel.content.fileNameInput.fill('any_file1.txt');
- await poHomeChannel.content.btnModalConfirm.click();
+ await poHomeChannel.composer.inputMessage.fill('any_description');
+ await poHomeChannel.composer.getFileByName(TEST_FILE_TXT).click();
+ await poHomeChannel.content.inputFileUploadName.fill('any_file1.txt');
+ await poHomeChannel.content.btnUpdateFileUpload.click();
+ await poHomeChannel.composer.btnSend.click();
await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).not.toBeVisible();
await expect(poHomeChannel.content.getFileDescription).toHaveText('any_description');
- await expect(poHomeChannel.content.getLastMessageByFileName('any_file1.txt')).toBeVisible();
+ await expect(poHomeChannel.content.getLastMessageByFileName('any_file1.txt')).toContainText('any_file1.txt');
});
});
});
diff --git a/apps/meteor/tests/e2e/file-upload.spec.ts b/apps/meteor/tests/e2e/file-upload.spec.ts
index a7a77ec903726..f864b6077c9ab 100644
--- a/apps/meteor/tests/e2e/file-upload.spec.ts
+++ b/apps/meteor/tests/e2e/file-upload.spec.ts
@@ -1,11 +1,17 @@
import { Users } from './fixtures/userStates';
import { HomeChannel } from './page-objects';
+import { FileUploadWarningModal } from './page-objects/fragments/modals';
import { createTargetChannel } from './utils';
import { setSettingValueById } from './utils/setSettingValueById';
import { expect, test } from './utils/test';
test.use({ storageState: Users.user1.state });
+const TEST_FILE_TXT = 'any_file.txt';
+const TEST_FILE_LST = 'lst-test.lst';
+const TEST_FILE_DRAWIO = 'diagram.drawio';
+const TEST_EMPTY_FILE = 'empty_file.txt';
+
test.describe.serial('file-upload', () => {
let poHomeChannel: HomeChannel;
let targetChannel: string;
@@ -27,55 +33,177 @@ test.describe.serial('file-upload', () => {
expect((await api.post('/channels.delete', { roomName: targetChannel })).status()).toBe(200);
});
- test('should successfully cancel upload', async () => {
+ test('should cancel uploaded file attached to message composer', async () => {
await poHomeChannel.content.dragAndDropTxtFile();
- await poHomeChannel.content.btnModalCancel.click();
- await expect(poHomeChannel.content.modalFilePreview).not.toBeVisible();
+ await poHomeChannel.composer.removeFileByName(TEST_FILE_TXT);
+
+ await expect(poHomeChannel.composer.getFileByName(TEST_FILE_TXT)).not.toBeVisible();
});
- test('should not display modal when clicking in send file', async () => {
- await poHomeChannel.content.dragAndDropTxtFile();
- await poHomeChannel.content.btnModalConfirm.click();
- await expect(poHomeChannel.content.modalFilePreview).not.toBeVisible();
+ test('should send file with name updated', async () => {
+ const updatedFileName = `edited_${TEST_FILE_TXT}`;
+ await poHomeChannel.content.sendFileMessage(TEST_FILE_TXT);
+
+ await test.step('update file name and send', async () => {
+ await poHomeChannel.composer.getFileByName(TEST_FILE_TXT).click();
+ await poHomeChannel.content.inputFileUploadName.fill(updatedFileName);
+ await poHomeChannel.content.btnUpdateFileUpload.click();
+
+ await expect(poHomeChannel.composer.getFileByName(updatedFileName)).toBeVisible();
+ await poHomeChannel.composer.btnSend.click();
+ });
+
+ await expect(poHomeChannel.content.getLastMessageByFileName(updatedFileName)).toContainText(updatedFileName);
});
- test('should send file with name/description updated', async () => {
- await poHomeChannel.content.dragAndDropTxtFile();
- await expect(poHomeChannel.content.descriptionInput).toBeFocused();
+ test('should attach multiple files and send one per message', async () => {
+ await poHomeChannel.content.sendFileMessage(TEST_FILE_TXT);
+ await poHomeChannel.content.sendFileMessage(TEST_FILE_LST);
+ await expect(poHomeChannel.composer.getFileByName(TEST_FILE_TXT)).toBeVisible();
+ await expect(poHomeChannel.composer.getFileByName(TEST_FILE_LST)).toBeVisible();
+
+ await poHomeChannel.composer.btnSend.click();
+ await expect(poHomeChannel.content.lastUserMessageDownloadLink).toHaveCount(1);
+ });
- await poHomeChannel.content.descriptionInput.fill('any_description');
- await poHomeChannel.content.fileNameInput.fill('any_file1.txt');
- await poHomeChannel.content.btnModalConfirm.click();
+ test('should not be able to attach files when editing a message', async () => {
+ await poHomeChannel.content.sendMessage('message to be edited');
+ await poHomeChannel.content.openLastMessageMenu();
+ await poHomeChannel.content.btnOptionEditMessage.click();
- await expect(poHomeChannel.content.getFileDescription).toHaveText('any_description');
- await expect(poHomeChannel.content.getLastMessageByFileName('any_file1.txt')).toBeVisible();
+ await poHomeChannel.content.dragAndDropTxtFile();
+ await expect(poHomeChannel.composer.getFileByName(TEST_FILE_TXT)).not.toBeVisible();
});
test('should send lst file successfully', async () => {
await poHomeChannel.content.dragAndDropLstFile();
- await poHomeChannel.content.descriptionInput.fill('lst_description');
- await poHomeChannel.content.btnModalConfirm.click();
+ await poHomeChannel.composer.inputMessage.fill('lst_description');
+ await poHomeChannel.composer.btnSend.click();
await expect(poHomeChannel.content.getFileDescription).toHaveText('lst_description');
- await expect(poHomeChannel.content.getLastMessageByFileName('lst-test.lst')).toBeVisible();
+ await expect(poHomeChannel.content.getLastMessageByFileName(TEST_FILE_LST)).toBeVisible();
});
test('should send drawio (unknown media type) file successfully', async ({ page }) => {
await page.reload();
- await poHomeChannel.content.sendFileMessage('diagram.drawio');
- await poHomeChannel.content.descriptionInput.fill('drawio_description');
- await poHomeChannel.content.btnModalConfirm.click();
+ await poHomeChannel.content.sendFileMessage(TEST_FILE_DRAWIO);
+ await poHomeChannel.composer.inputMessage.fill('drawio_description');
+ await poHomeChannel.composer.btnSend.click();
await expect(poHomeChannel.content.getFileDescription).toHaveText('drawio_description');
- await expect(poHomeChannel.content.getLastMessageByFileName('diagram.drawio')).toBeVisible();
+ await expect(poHomeChannel.content.getLastMessageByFileName(TEST_FILE_DRAWIO)).toBeVisible();
});
test('should not to send drawio file (unknown media type) when the default media type is blocked', async ({ api, page }) => {
await setSettingValueById(api, 'FileUpload_MediaTypeBlackList', 'application/octet-stream');
await page.reload();
- await poHomeChannel.content.sendFileMessage('diagram.drawio');
- await expect(poHomeChannel.content.btnModalConfirm).not.toBeVisible();
+ await poHomeChannel.content.sendFileMessage(TEST_FILE_DRAWIO, { waitForResponse: false });
+
+ await expect(poHomeChannel.composer.getFileByName(TEST_FILE_DRAWIO)).toHaveAttribute('readonly');
+ });
+
+ test('should be able to remove file from composer before sending', async () => {
+ await poHomeChannel.content.sendFileMessage(TEST_FILE_TXT);
+ await poHomeChannel.content.sendFileMessage(TEST_FILE_LST);
+
+ await poHomeChannel.composer.removeFileByName(TEST_FILE_TXT);
+
+ await expect(poHomeChannel.composer.getFileByName(TEST_FILE_TXT)).not.toBeVisible();
+ await expect(poHomeChannel.composer.getFileByName(TEST_FILE_LST)).toBeVisible();
+
+ await poHomeChannel.composer.btnSend.click();
+
+ await expect(poHomeChannel.content.lastUserMessage).not.toContainText(TEST_FILE_TXT);
+ await expect(poHomeChannel.content.lastUserMessage).toContainText(TEST_FILE_LST);
+ });
+
+ test('should respect the maximum number of files allowed per message: 10', async () => {
+ const files = new Array(10).fill('number1.png');
+
+ await Promise.all(files.map((file) => poHomeChannel.content.sendFileMessage(file)));
+ await poHomeChannel.content.dragAndDropTxtFile();
+
+ await expect(poHomeChannel.composer.getFilesInComposer()).toHaveCount(10);
+ await expect(poHomeChannel.composer.getFileByName('any_file.txt')).not.toBeVisible();
+ });
+
+ test.describe.serial('thread multiple file upload', () => {
+ test('should be able to remove file from thread composer before sending', async () => {
+ await poHomeChannel.content.sendMessage('this is a message for thread reply');
+ await poHomeChannel.content.openReplyInThread();
+ await poHomeChannel.content.sendFileMessageToThread(TEST_FILE_TXT);
+ await poHomeChannel.content.sendFileMessageToThread(TEST_FILE_LST);
+
+ await poHomeChannel.threadComposer.removeFileByName(TEST_FILE_LST);
+
+ await expect(poHomeChannel.threadComposer.getFileByName(TEST_FILE_TXT)).toBeVisible();
+ await expect(poHomeChannel.threadComposer.getFileByName(TEST_FILE_LST)).not.toBeVisible();
+ });
+ });
+
+ test.describe.serial('file upload fails', () => {
+ let fileUploadWarningModal: FileUploadWarningModal;
+
+ test.beforeAll(async ({ api }) => {
+ await setSettingValueById(api, 'FileUpload_MediaTypeBlackList', 'application/octet-stream');
+ });
+
+ test.afterAll(async ({ api }) => {
+ await setSettingValueById(api, 'FileUpload_MediaTypeBlackList', 'image/svg+xml');
+ });
+
+ test('should open warning modal when all file uploads fail', async ({ page }) => {
+ fileUploadWarningModal = new FileUploadWarningModal(page.getByRole('dialog', { name: 'Warning' }));
+
+ await poHomeChannel.content.sendFileMessage(TEST_EMPTY_FILE, { waitForResponse: false });
+ await poHomeChannel.content.sendFileMessage(TEST_FILE_DRAWIO, { waitForResponse: false });
+
+ await expect(poHomeChannel.composer.getFileByName(TEST_EMPTY_FILE)).toHaveAttribute('readonly');
+ await expect(poHomeChannel.composer.getFileByName(TEST_FILE_DRAWIO)).toHaveAttribute('readonly');
+
+ await poHomeChannel.composer.btnSend.click();
+ await fileUploadWarningModal.waitForDisplay();
+
+ await expect(fileUploadWarningModal.getContent('2 files failed to upload')).toBeVisible();
+ await expect(fileUploadWarningModal.btnOk).toBeVisible();
+ await expect(fileUploadWarningModal.btnSendAnyway).not.toBeVisible();
+ });
+
+ test('should handle multiple files with one failing upload', async ({ page }) => {
+ fileUploadWarningModal = new FileUploadWarningModal(page.getByRole('dialog', { name: 'Are you sure' }));
+
+ await test.step('should only mark as "Upload failed" the specific file that failed to upload', async () => {
+ await poHomeChannel.content.sendFileMessage(TEST_FILE_TXT, { waitForResponse: false });
+ await poHomeChannel.content.sendFileMessage(TEST_EMPTY_FILE, { waitForResponse: false });
+
+ await expect(poHomeChannel.composer.getFileByName(TEST_FILE_TXT)).not.toHaveAttribute('readonly');
+ await expect(poHomeChannel.composer.getFileByName(TEST_EMPTY_FILE)).toHaveAttribute('readonly');
+ });
+
+ await test.step('should open warning modal', async () => {
+ await poHomeChannel.composer.btnSend.click();
+ await fileUploadWarningModal.waitForDisplay();
+
+ await expect(fileUploadWarningModal.getContent('One file failed to upload')).toBeVisible();
+ });
+
+ await test.step('should close modal when clicking "Cancel" button', async () => {
+ await fileUploadWarningModal.cancel();
+
+ await expect(poHomeChannel.composer.getFileByName(TEST_EMPTY_FILE)).toBeVisible();
+ await expect(poHomeChannel.composer.getFileByName(TEST_FILE_TXT)).toBeVisible();
+ });
+
+ await test.step('should send message with the valid file when confirming "Send anyway"', async () => {
+ await poHomeChannel.composer.btnSend.click();
+ await fileUploadWarningModal.confirmSend();
+
+ await expect(poHomeChannel.composer.getFileByName(TEST_FILE_TXT)).not.toBeVisible();
+ await expect(poHomeChannel.content.getLastMessageByFileName(TEST_FILE_TXT)).toContainText(TEST_FILE_TXT);
+ await expect(poHomeChannel.composer.getFileByName(TEST_EMPTY_FILE)).not.toBeVisible();
+ });
+ });
});
});
@@ -100,6 +228,6 @@ test.describe('file-upload-not-member', () => {
test('should not be able to upload if not a member', async () => {
await poHomeChannel.content.dragAndDropTxtFile();
- await expect(poHomeChannel.content.modalFilePreview).not.toBeVisible();
+ await expect(poHomeChannel.composer.getFileByName(TEST_FILE_TXT)).not.toBeVisible();
});
});
diff --git a/apps/meteor/tests/e2e/files-management.spec.ts b/apps/meteor/tests/e2e/files-management.spec.ts
index 2f193e614437d..55d9e41dcb172 100644
--- a/apps/meteor/tests/e2e/files-management.spec.ts
+++ b/apps/meteor/tests/e2e/files-management.spec.ts
@@ -28,7 +28,7 @@ test.describe.serial('files-management', () => {
test('should send a file and manage it in the list', async () => {
await poHomeChannel.content.dragAndDropTxtFile();
- await poHomeChannel.content.btnModalConfirm.click();
+ await poHomeChannel.composer.btnSend.click();
await expect(poHomeChannel.content.getLastMessageByFileName(TEST_FILE_TXT)).toBeVisible();
await poHomeChannel.roomToolbar.openMoreOptions();
diff --git a/apps/meteor/tests/e2e/fixtures/files/another_file.txt b/apps/meteor/tests/e2e/fixtures/files/another_file.txt
new file mode 100644
index 0000000000000..ad7bbe091558e
--- /dev/null
+++ b/apps/meteor/tests/e2e/fixtures/files/another_file.txt
@@ -0,0 +1 @@
+another_file
diff --git a/apps/meteor/tests/e2e/fixtures/files/empty_file.txt b/apps/meteor/tests/e2e/fixtures/files/empty_file.txt
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/apps/meteor/tests/e2e/fixtures/responses/mediaResponse.ts b/apps/meteor/tests/e2e/fixtures/responses/mediaResponse.ts
new file mode 100644
index 0000000000000..ed0c6fe9ca3e3
--- /dev/null
+++ b/apps/meteor/tests/e2e/fixtures/responses/mediaResponse.ts
@@ -0,0 +1,8 @@
+import type { Page, Response } from '@playwright/test';
+
+const isMediaResponse = (response: Response) =>
+ /api\/v1\/rooms\.media(?:\/|\?|$)/.test(response.url()) && response.request().method() === 'POST';
+
+export const createMediaResponsePromise = (page: Page) => {
+ return page.waitForResponse((response) => isMediaResponse(response));
+};
diff --git a/apps/meteor/tests/e2e/image-gallery.spec.ts b/apps/meteor/tests/e2e/image-gallery.spec.ts
index b4afdcbe19054..9dc2a4368d62f 100644
--- a/apps/meteor/tests/e2e/image-gallery.spec.ts
+++ b/apps/meteor/tests/e2e/image-gallery.spec.ts
@@ -38,17 +38,19 @@ test.describe.serial('Image Gallery', async () => {
test.describe('When sending an image as a file', () => {
test.beforeAll(async () => {
+ const largeFileName = 'test-large-image.jpeg';
+
await poHomeChannel.navbar.openChat(targetChannel);
for await (const imageName of imageNames) {
await poHomeChannel.content.sendFileMessage(imageName);
- await poHomeChannel.content.btnModalConfirm.click();
+ await poHomeChannel.composer.btnSend.click();
await expect(poHomeChannel.content.lastUserMessage).toContainText(imageName);
}
await poHomeChannel.navbar.openChat(targetChannelLargeImage);
- await poHomeChannel.content.sendFileMessage('test-large-image.jpeg');
- await poHomeChannel.content.btnModalConfirm.click();
- await expect(poHomeChannel.content.lastUserMessage).toContainText('test-large-image.jpeg');
+ await poHomeChannel.content.sendFileMessage(largeFileName);
+ await poHomeChannel.composer.btnSend.click();
+ await expect(poHomeChannel.content.lastUserMessage).toContainText(largeFileName);
await poHomeChannel.content.lastUserMessage.locator('img.gallery-item').click();
});
diff --git a/apps/meteor/tests/e2e/image-upload.spec.ts b/apps/meteor/tests/e2e/image-upload.spec.ts
index 77f8dc7c8dffe..3e19f8ae945db 100644
--- a/apps/meteor/tests/e2e/image-upload.spec.ts
+++ b/apps/meteor/tests/e2e/image-upload.spec.ts
@@ -36,11 +36,8 @@ test.describe('image-upload', () => {
test('should show error indicator when upload fails', async () => {
await poHomeChannel.content.sendFileMessage('bad-orientation.jpeg');
- await poHomeChannel.content.fileNameInput.fill('bad-orientation.jpeg');
- await poHomeChannel.content.descriptionInput.fill('bad-orientation_description');
- await poHomeChannel.content.btnModalConfirm.click();
- await expect(poHomeChannel.statusUploadError).toBeVisible();
+ await expect(poHomeChannel.composer.getFileByName('bad-orientation.jpeg')).toHaveAttribute('readonly');
});
});
@@ -52,12 +49,10 @@ test.describe('image-upload', () => {
});
test('should succeed upload of bad-orientation.jpeg', async () => {
- await poHomeChannel.content.sendFileMessage('bad-orientation.jpeg');
- await poHomeChannel.content.fileNameInput.fill('bad-orientation.jpeg');
- await poHomeChannel.content.descriptionInput.fill('bad-orientation_description');
- await poHomeChannel.content.btnModalConfirm.click();
-
- await expect(poHomeChannel.content.getFileDescription).toHaveText('bad-orientation_description');
+ const imgName = 'bad-orientation.jpeg';
+ await poHomeChannel.content.sendFileMessage(imgName);
+ await poHomeChannel.composer.btnSend.click();
+ await expect(poHomeChannel.content.lastUserMessage).toContainText(imgName);
});
});
});
diff --git a/apps/meteor/tests/e2e/message-actions.spec.ts b/apps/meteor/tests/e2e/message-actions.spec.ts
index d39a3ea33c808..3a1e71733ca02 100644
--- a/apps/meteor/tests/e2e/message-actions.spec.ts
+++ b/apps/meteor/tests/e2e/message-actions.spec.ts
@@ -225,7 +225,7 @@ test.describe.serial('message-actions', () => {
test('expect forward text file to channel', async () => {
const filename = 'any_file.txt';
await poHomeChannel.content.sendFileMessage(filename);
- await poHomeChannel.content.btnModalConfirm.click();
+ await poHomeChannel.composer.btnSend.click();
await expect(poHomeChannel.content.lastUserMessage).toContainText(filename);
await poHomeChannel.content.forwardMessage(forwardChannel);
@@ -237,7 +237,7 @@ test.describe.serial('message-actions', () => {
test('expect forward image file to channel', async () => {
const filename = 'test-image.jpeg';
await poHomeChannel.content.sendFileMessage(filename);
- await poHomeChannel.content.btnModalConfirm.click();
+ await poHomeChannel.composer.btnSend.click();
await expect(poHomeChannel.content.lastUserMessage).toContainText(filename);
await poHomeChannel.content.forwardMessage(forwardChannel);
@@ -249,7 +249,7 @@ test.describe.serial('message-actions', () => {
test('expect forward pdf file to channel', async () => {
const filename = 'test_pdf_file.pdf';
await poHomeChannel.content.sendFileMessage(filename);
- await poHomeChannel.content.btnModalConfirm.click();
+ await poHomeChannel.composer.btnSend.click();
await expect(poHomeChannel.content.lastUserMessage).toContainText(filename);
await poHomeChannel.content.forwardMessage(forwardChannel);
@@ -261,7 +261,7 @@ test.describe.serial('message-actions', () => {
test('expect forward audio message to channel', async () => {
const filename = 'sample-audio.mp3';
await poHomeChannel.content.sendFileMessage(filename);
- await poHomeChannel.content.btnModalConfirm.click();
+ await poHomeChannel.composer.btnSend.click();
await expect(poHomeChannel.content.lastUserMessage).toContainText(filename);
await poHomeChannel.content.forwardMessage(forwardChannel);
@@ -273,7 +273,7 @@ test.describe.serial('message-actions', () => {
test('expect forward video message to channel', async () => {
const filename = 'test_video.mp4';
await poHomeChannel.content.sendFileMessage(filename);
- await poHomeChannel.content.btnModalConfirm.click();
+ await poHomeChannel.composer.btnSend.click();
await expect(poHomeChannel.content.lastUserMessage).toContainText(filename);
await poHomeChannel.content.forwardMessage(forwardChannel);
diff --git a/apps/meteor/tests/e2e/message-composer.spec.ts b/apps/meteor/tests/e2e/message-composer.spec.ts
index 8b203d4d93fcf..5816ec4783bfa 100644
--- a/apps/meteor/tests/e2e/message-composer.spec.ts
+++ b/apps/meteor/tests/e2e/message-composer.spec.ts
@@ -189,14 +189,14 @@ test.describe.serial('message-composer', () => {
await expect(poHomeChannel.audioRecorder).not.toBeVisible();
});
- test('should open file modal when clicking on "Finish recording"', async ({ page }) => {
+ test('should attach file to the composer when clicking on "Finish recording"', async ({ page }) => {
await poHomeChannel.navbar.openChat(targetChannel);
await poHomeChannel.composer.btnAudioMessage.click();
await expect(poHomeChannel.audioRecorder).toBeVisible();
await page.waitForTimeout(1000);
await poHomeChannel.audioRecorder.getByRole('button', { name: 'Finish Recording', exact: true }).click();
- await expect(poHomeChannel.content.fileUploadModal).toBeVisible();
+ await expect(poHomeChannel.composer.getFileByName('Audio record.mp3')).toBeVisible();
});
});
});
diff --git a/apps/meteor/tests/e2e/page-objects/fragments/composer.ts b/apps/meteor/tests/e2e/page-objects/fragments/composer.ts
index e3ecc115e52b1..675276e3cd98c 100644
--- a/apps/meteor/tests/e2e/page-objects/fragments/composer.ts
+++ b/apps/meteor/tests/e2e/page-objects/fragments/composer.ts
@@ -29,6 +29,22 @@ export abstract class Composer {
return this.toolbarPrimaryActions.getByRole('button', { name: 'Audio message' });
}
+ getFileByName(fileName: string): Locator {
+ return this.root.getByRole('group', { name: fileName, exact: true });
+ }
+
+ get groupUploads() {
+ return this.root.getByRole('group', { name: 'Uploads', exact: true });
+ }
+
+ getFilesInComposer(): Locator {
+ return this.groupUploads.getByRole('group', { name: /^(?!Close$)/ });
+ }
+
+ async removeFileByName(fileName: string): Promise {
+ return this.getFileByName(fileName).getByRole('button', { name: 'Remove', exact: true }).click();
+ }
+
get btnSend(): Locator {
return this.root.getByRole('button', { name: 'Send' });
}
diff --git a/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts b/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts
index 0b0831603651d..acb2f29d94d12 100644
--- a/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts
+++ b/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts
@@ -4,6 +4,7 @@ import { resolve, join, relative } from 'node:path';
import type { Locator, Page } from '@playwright/test';
import { RoomComposer, ThreadComposer } from './composer';
+import { createMediaResponsePromise } from '../../fixtures/responses/mediaResponse';
import { expect } from '../../utils/test';
const FIXTURES_PATH = relative(process.cwd(), resolve(__dirname, '../../fixtures/files'));
@@ -15,7 +16,7 @@ export function getFilePath(fileName: string): string {
export class HomeContent {
protected readonly page: Page;
- protected readonly composer: RoomComposer;
+ readonly composer: RoomComposer;
protected readonly threadComposer: ThreadComposer;
@@ -73,6 +74,10 @@ export class HomeContent {
return this.page.getByRole('listitem').locator('[role="link"][aria-roledescription="thread message preview"]').last();
}
+ get lastUserMessageDownloadLink(): Locator {
+ return this.lastUserMessage.getByRole('link', { name: 'Download' });
+ }
+
nthMessage(index: number): Locator {
return this.messageListItems.nth(index);
}
@@ -158,7 +163,7 @@ export class HomeContent {
return this.page.locator('#modal-root .rcx-button-group--align-end .rcx-button--secondary');
}
- get fileUploadModal(): Locator {
+ private get fileUploadModal(): Locator {
return this.page.getByRole('dialog', { name: 'File Upload' });
}
@@ -174,12 +179,6 @@ export class HomeContent {
return this.createDiscussionModal.getByRole('button', { name: 'Create' });
}
- get modalFilePreview(): Locator {
- return this.page.locator(
- '//div[@id="modal-root"]//header//following-sibling::div[1]//div//div//img | //div[@id="modal-root"]//header//following-sibling::div[1]//div//div//div//i',
- );
- }
-
get btnModalConfirm(): Locator {
return this.page.locator('#modal-root .rcx-button-group--align-end .rcx-button--primary');
}
@@ -192,16 +191,20 @@ export class HomeContent {
return this.page.getByRole('button', { name: 'Dismiss quoted message' });
}
- get descriptionInput(): Locator {
- return this.page.locator('//div[@id="modal-root"]//fieldset//div[2]//span//input');
- }
-
get getFileDescription(): Locator {
return this.lastUserMessage.locator('[role="document"][aria-roledescription="message body"]');
}
- get fileNameInput(): Locator {
- return this.page.locator('//div[@id="modal-root"]//fieldset//div[1]//span//input');
+ get inputFileUploadName(): Locator {
+ return this.fileUploadModal.getByRole('textbox', { name: 'File name' });
+ }
+
+ get btnUpdateFileUpload(): Locator {
+ return this.fileUploadModal.getByRole('button', { name: 'Update' });
+ }
+
+ get btnCancelUpdateFileUpload(): Locator {
+ return this.fileUploadModal.getByRole('button', { name: 'Cancel' });
}
// -----------------------------------------
@@ -374,7 +377,7 @@ export class HomeContent {
await this.page.locator('[role=dialog][data-qa="DropTargetOverlay"]').dispatchEvent('drop', { dataTransfer });
}
- async dragAndDropLstFile(): Promise {
+ async dragAndDropLstFile({ waitForResponse = true }: { waitForResponse?: boolean } = {}): Promise {
const contract = await fs.readFile(getFilePath('lst-test.lst'), 'utf-8');
const dataTransfer = await this.page.evaluateHandle((contract) => {
const data = new DataTransfer();
@@ -385,12 +388,15 @@ export class HomeContent {
return data;
}, contract);
+ const responsePromise = waitForResponse ? createMediaResponsePromise(this.page) : null;
await this.composer.inputMessage.dispatchEvent('dragenter', { dataTransfer });
-
await this.page.locator('[role=dialog][data-qa="DropTargetOverlay"]').dispatchEvent('drop', { dataTransfer });
+ if (responsePromise) {
+ await responsePromise;
+ }
}
- async dragAndDropTxtFileToThread(): Promise {
+ async dragAndDropTxtFileToThread({ waitForResponse = true }: { waitForResponse?: boolean } = {}): Promise {
const contract = await fs.readFile(getFilePath('any_file.txt'), 'utf-8');
const dataTransfer = await this.page.evaluateHandle((contract) => {
const data = new DataTransfer();
@@ -401,13 +407,29 @@ export class HomeContent {
return data;
}, contract);
+ const responsePromise = waitForResponse ? createMediaResponsePromise(this.page) : null;
await this.threadComposer.inputMessage.dispatchEvent('dragenter', { dataTransfer });
-
await this.page.locator('[role=dialog][data-qa="DropTargetOverlay"]').dispatchEvent('drop', { dataTransfer });
+ if (responsePromise) {
+ await responsePromise;
+ }
}
- async sendFileMessage(fileName: string): Promise {
- await this.page.locator('input[type=file]').setInputFiles(getFilePath(fileName));
+ async sendFileMessage(fileName: string, { waitForResponse = true }: { waitForResponse?: boolean } = {}): Promise {
+ const responsePromise = waitForResponse ? createMediaResponsePromise(this.page) : null;
+ await this.page.getByLabel('Room composer').locator('input[type=file]').setInputFiles(getFilePath(fileName));
+ if (responsePromise) {
+ await responsePromise;
+ }
+ }
+
+ async sendFileMessageToThread(fileName: string, { waitForResponse = true }: { waitForResponse?: boolean } = {}): Promise {
+ await this.threadComposer.inputMessage.click();
+ const responsePromise = waitForResponse ? createMediaResponsePromise(this.page) : null;
+ await this.page.getByLabel('Thread composer').locator('input[type=file]').setInputFiles(getFilePath(fileName));
+ if (responsePromise) {
+ await responsePromise;
+ }
}
async openLastMessageMenu(): Promise {
diff --git a/apps/meteor/tests/e2e/page-objects/fragments/modals/file-upload-modal.ts b/apps/meteor/tests/e2e/page-objects/fragments/modals/file-upload-modal.ts
index 92f2915827efa..7ea0d658d6488 100644
--- a/apps/meteor/tests/e2e/page-objects/fragments/modals/file-upload-modal.ts
+++ b/apps/meteor/tests/e2e/page-objects/fragments/modals/file-upload-modal.ts
@@ -1,4 +1,4 @@
-import type { Page } from '@playwright/test';
+import type { Locator, Page } from '@playwright/test';
import { Modal } from './modal';
@@ -7,28 +7,52 @@ export class FileUploadModal extends Modal {
super(page.getByRole('dialog', { name: 'File Upload' }));
}
- private get fileNameInput() {
+ private get inputFileName() {
return this.root.getByRole('textbox', { name: 'File name' });
}
- private get fileDescriptionInput() {
- return this.root.getByRole('textbox', { name: 'File description' });
+ private get updateButton() {
+ return this.root.getByRole('button', { name: 'Update' });
}
- private get sendButton() {
- return this.root.getByRole('button', { name: 'Send' });
+ setName(fileName: string) {
+ return this.inputFileName.fill(fileName);
}
- setName(fileName: string) {
- return this.fileNameInput.fill(fileName);
+ async update() {
+ await this.updateButton.click();
+ await this.waitForDismissal();
+ }
+}
+
+export class FileUploadWarningModal extends Modal {
+ constructor(root: Locator) {
+ super(root);
+ }
+
+ get btnOk() {
+ return this.root.getByRole('button', { name: 'Ok' });
}
- setDescription(description: string) {
- return this.fileDescriptionInput.fill(description);
+ get btnSendAnyway() {
+ return this.root.getByRole('button', { name: 'Send anyway' });
+ }
+
+ getContent(text: string) {
+ return this.root.getByText(text);
+ }
+
+ private get btnCancel() {
+ return this.root.getByRole('button', { name: 'Cancel' });
+ }
+
+ async cancel() {
+ await this.btnCancel.click();
+ await this.waitForDismissal();
}
- async send() {
- await this.sendButton.click();
+ async confirmSend() {
+ await this.btnSendAnyway.click();
await this.waitForDismissal();
}
}
diff --git a/apps/meteor/tests/e2e/page-objects/home-channel.ts b/apps/meteor/tests/e2e/page-objects/home-channel.ts
index 3a838eff0b61d..5c953ff072acf 100644
--- a/apps/meteor/tests/e2e/page-objects/home-channel.ts
+++ b/apps/meteor/tests/e2e/page-objects/home-channel.ts
@@ -97,10 +97,6 @@ export class HomeChannel {
return this.page.getByRole('group', { name: 'Audio recorder', exact: true });
}
- get statusUploadError(): Locator {
- return this.page.getByRole('main').getByRole('status').getByText('Error');
- }
-
get homepageHeader(): Locator {
return this.page.locator('main').getByRole('heading', { name: 'Home' });
}
diff --git a/apps/meteor/tests/e2e/prune-messages.spec.ts b/apps/meteor/tests/e2e/prune-messages.spec.ts
index 0845ebcdf2911..ea668588453a9 100644
--- a/apps/meteor/tests/e2e/prune-messages.spec.ts
+++ b/apps/meteor/tests/e2e/prune-messages.spec.ts
@@ -42,8 +42,8 @@ test.describe('prune-messages', () => {
} = poHomeChannel;
await content.sendFileMessage('any_file.txt');
- await content.descriptionInput.fill('a message with a file');
- await content.btnModalConfirm.click();
+ await expect(content.composer.getFileByName('any_file.txt')).toBeVisible();
+ await poHomeChannel.composer.btnSend.click();
await expect(content.getLastMessageByFileName('any_file.txt')).toBeVisible();
await sendTargetChannelMessage(api, targetChannel.fname as string, {
@@ -110,8 +110,7 @@ test.describe('prune-messages', () => {
} = poHomeChannel;
await content.sendFileMessage('any_file.txt');
- await content.descriptionInput.fill('a message with a file');
- await content.btnModalConfirm.click();
+ await poHomeChannel.composer.btnSend.click();
await expect(content.getLastMessageByFileName('any_file.txt')).toBeVisible();
await test.step('prune files only', async () => {
@@ -145,8 +144,7 @@ test.describe('prune-messages', () => {
const { content } = poHomeChannel;
await content.sendFileMessage('any_file.txt');
- await content.descriptionInput.fill('a message with a file');
- await content.btnModalConfirm.click();
+ await poHomeChannel.composer.btnSend.click();
await expect(content.getLastMessageByFileName('any_file.txt')).toBeVisible();
await content.openReplyInThread();
diff --git a/apps/meteor/tests/e2e/quote-attachment.spec.ts b/apps/meteor/tests/e2e/quote-attachment.spec.ts
index 86f7c639205ba..2630e2bcbe3d5 100644
--- a/apps/meteor/tests/e2e/quote-attachment.spec.ts
+++ b/apps/meteor/tests/e2e/quote-attachment.spec.ts
@@ -30,9 +30,8 @@ test.describe.parallel('Quote Attachment', () => {
const imageFileName = 'test-image.jpeg';
await test.step('Send message with attachment in the channel', async () => {
await poHomeChannel.content.sendFileMessage(imageFileName);
- await poHomeChannel.content.fileNameInput.fill(imageFileName);
- await poHomeChannel.content.descriptionInput.fill(fileDescription);
- await poHomeChannel.content.btnModalConfirm.click();
+ await poHomeChannel.composer.inputMessage.fill(fileDescription);
+ await poHomeChannel.composer.btnSend.click();
// Wait for the file to be uploaded and message to be sent
await expect(poHomeChannel.content.lastUserMessage).toBeVisible();
@@ -58,7 +57,7 @@ test.describe.parallel('Quote Attachment', () => {
});
test('should show file preview and description when quoting attachment file within a thread', async ({ page }) => {
- const textFileName = 'any_file1.txt';
+ const textFileName = 'any_file.txt';
await test.step('Send initial message in channel', async () => {
await poHomeChannel.content.sendMessage('Initial message for thread test');
@@ -71,9 +70,7 @@ test.describe.parallel('Quote Attachment', () => {
await expect(page).toHaveURL(/.*thread/);
await poHomeChannel.content.dragAndDropTxtFileToThread();
- await poHomeChannel.content.descriptionInput.fill(fileDescription);
- await poHomeChannel.content.fileNameInput.fill(textFileName);
- await poHomeChannel.content.btnModalConfirm.click();
+ await poHomeChannel.content.sendMessageInThread(fileDescription);
await expect(poHomeChannel.content.lastThreadMessageFileDescription).toHaveText(fileDescription);
await expect(poHomeChannel.content.getLastThreadMessageByFileName(textFileName)).toBeVisible();
diff --git a/apps/meteor/tests/e2e/threads.spec.ts b/apps/meteor/tests/e2e/threads.spec.ts
index 2ceb6e37f3c71..fca7f74d917a5 100644
--- a/apps/meteor/tests/e2e/threads.spec.ts
+++ b/apps/meteor/tests/e2e/threads.spec.ts
@@ -78,18 +78,21 @@ test.describe.serial('Threads', () => {
await expect(poHomeChannel.content.lastUserThreadMessage).toContainText('This is a thread message also sent in channel');
});
});
- test('expect upload a file attachment in thread with description', async ({ page }) => {
+ test('should send a file with name updated in thread', async ({ page }) => {
+ const updatedFileName = 'any_file1.txt';
await poHomeChannel.content.lastThreadMessagePreviewText.click();
await expect(page).toHaveURL(/.*thread/);
await poHomeChannel.content.dragAndDropTxtFileToThread();
- await poHomeChannel.content.descriptionInput.fill('any_description');
- await poHomeChannel.content.fileNameInput.fill('any_file1.txt');
- await poHomeChannel.content.btnModalConfirm.click();
+ await poHomeChannel.threadComposer.getFileByName('any_file.txt').click();
+ await poHomeChannel.content.inputFileUploadName.fill(updatedFileName);
+ await poHomeChannel.content.btnUpdateFileUpload.click();
+ await poHomeChannel.threadComposer.inputMessage.fill('any_description');
+ await poHomeChannel.threadComposer.btnSend.click();
await expect(poHomeChannel.content.lastThreadMessageFileDescription).toHaveText('any_description');
- await expect(poHomeChannel.content.getLastThreadMessageByFileName('any_file1.txt')).toBeVisible();
+ await expect(poHomeChannel.content.getLastThreadMessageByFileName(updatedFileName)).toBeVisible();
});
test.describe('thread message actions', () => {
diff --git a/package.json b/package.json
index 4d066cabbb3f0..ff9c9b65ba9e0 100644
--- a/package.json
+++ b/package.json
@@ -35,19 +35,6 @@
"testunit": "turbo run testunit"
},
"resolutions": {
- "@react-pdf/fns": "2.0.1",
- "@react-pdf/font": "2.3.7",
- "@react-pdf/image": "2.2.2",
- "@react-pdf/layout": "3.6.3",
- "@react-pdf/pdfkit": "3.0.2",
- "@react-pdf/png-js": "2.2.0",
- "@react-pdf/primitives": "3.0.1",
- "@react-pdf/render": "3.2.7",
- "@react-pdf/renderer": "3.1.14",
- "@react-pdf/stylesheet": "4.1.8",
- "@react-pdf/textkit": "4.2.0",
- "@react-pdf/types": "2.3.4",
- "@react-pdf/yoga": "4.1.2",
"@sematext/gc-stats@npm:^1.5.9": "patch:@sematext/gc-stats@npm%3A1.5.9#~/.yarn/patches/@sematext-gc-stats-npm-1.5.9-01e77be4d0.patch",
"adm-zip": "0.5.9",
"cross-spawn": "7.0.6",
@@ -55,7 +42,9 @@
"lodash": "4.17.21",
"minimist": "1.2.6",
"mongodb": "6.10.0",
- "underscore": "1.13.7"
+ "underscore": "1.13.7",
+ "yoga-layout@npm:^3.2.1": "patch:yoga-layout@npm%3A3.2.1#~/.yarn/patches/yoga-layout-npm-3.2.1-51ec934670.patch",
+ "@react-pdf/layout@npm:^4.4.2": "patch:@react-pdf/layout@npm%3A4.4.2#~/.yarn/patches/@react-pdf-layout-npm-4.4.2-6c2e3312fa.patch"
},
"dependencies": {
"@types/stream-buffers": "^3.0.8",
diff --git a/packages/core-typings/src/IUpload.ts b/packages/core-typings/src/IUpload.ts
index 660a498badb74..ee8f11c511b42 100644
--- a/packages/core-typings/src/IUpload.ts
+++ b/packages/core-typings/src/IUpload.ts
@@ -74,4 +74,6 @@ export interface IE2EEUpload extends IUpload {
content: EncryptedContent;
}
+export type IUploadToConfirm = Pick;
+
export const isE2EEUpload = (upload: IUpload): upload is IE2EEUpload => Boolean(upload?.content?.ciphertext && upload?.content?.algorithm);
diff --git a/packages/i18n/src/locales/af.i18n.json b/packages/i18n/src/locales/af.i18n.json
index f3c6cfa28c522..95b2ec5254b5e 100644
--- a/packages/i18n/src/locales/af.i18n.json
+++ b/packages/i18n/src/locales/af.i18n.json
@@ -2175,7 +2175,6 @@
"Updated_at": "Opgedateer op",
"UpgradeToGetMore_engagement-dashboard_Title": "Analytics",
"Upload_Folder_Path": "Laai mappad op",
- "Upload_file_description": "Lêer beskrywing",
"Upload_file_name": "Lêernaam",
"Upload_file_question": "Laai leêr op?",
"Upload_user_avatar": "Laai avatar op",
diff --git a/packages/i18n/src/locales/ar.i18n.json b/packages/i18n/src/locales/ar.i18n.json
index b03d597651d0a..a9ec900089a61 100644
--- a/packages/i18n/src/locales/ar.i18n.json
+++ b/packages/i18n/src/locales/ar.i18n.json
@@ -3808,7 +3808,6 @@
"Upload_Folder_Path": "تحميل مسار المجلد",
"Upload_From": "تحميل من {{name}}",
"Upload_app": "تحميل التطبيق",
- "Upload_file_description": "وصف الملف",
"Upload_file_name": "اسم الملف",
"Upload_file_question": "تحميل الملف؟",
"Upload_user_avatar": "تحميل الصورة الرمزية",
diff --git a/packages/i18n/src/locales/az.i18n.json b/packages/i18n/src/locales/az.i18n.json
index ebd3b2252cf87..790aaacd1f6a8 100644
--- a/packages/i18n/src/locales/az.i18n.json
+++ b/packages/i18n/src/locales/az.i18n.json
@@ -2177,7 +2177,6 @@
"Updated_at": "Yenilənib",
"UpgradeToGetMore_engagement-dashboard_Title": "Analytics",
"Upload_Folder_Path": "Qovluq yolunu yükləyin",
- "Upload_file_description": "Fayl təsviri",
"Upload_file_name": "Fayl adı",
"Upload_file_question": "Fayl yükləməyiniz?",
"Upload_user_avatar": "Avatar yüklə",
diff --git a/packages/i18n/src/locales/be-BY.i18n.json b/packages/i18n/src/locales/be-BY.i18n.json
index a392d811166b7..421f45fb9c492 100644
--- a/packages/i18n/src/locales/be-BY.i18n.json
+++ b/packages/i18n/src/locales/be-BY.i18n.json
@@ -2196,7 +2196,6 @@
"Updated_at": "абноўлена",
"UpgradeToGetMore_engagement-dashboard_Title": "аналітыка",
"Upload_Folder_Path": "Загрузіць шлях да тэчцы",
- "Upload_file_description": "апісанне файла",
"Upload_file_name": "Імя файла",
"Upload_file_question": "Загрузіць файл?",
"Upload_user_avatar": "загрузіць аватар",
diff --git a/packages/i18n/src/locales/bg.i18n.json b/packages/i18n/src/locales/bg.i18n.json
index fb3a9857d9f5d..84720df14e7bd 100644
--- a/packages/i18n/src/locales/bg.i18n.json
+++ b/packages/i18n/src/locales/bg.i18n.json
@@ -2172,7 +2172,6 @@
"Updated_at": "Актуализиран на",
"UpgradeToGetMore_engagement-dashboard_Title": "анализ",
"Upload_Folder_Path": "Качване на пътя на папките",
- "Upload_file_description": "Описание на файла",
"Upload_file_name": "Име на файл",
"Upload_file_question": "Качи фаил?",
"Upload_user_avatar": "Качване на аватар",
diff --git a/packages/i18n/src/locales/bs.i18n.json b/packages/i18n/src/locales/bs.i18n.json
index db84696611cf8..616b825bfba9d 100644
--- a/packages/i18n/src/locales/bs.i18n.json
+++ b/packages/i18n/src/locales/bs.i18n.json
@@ -2169,7 +2169,6 @@
"Updated_at": "Ažurirano u",
"UpgradeToGetMore_engagement-dashboard_Title": "Analitika",
"Upload_Folder_Path": "Prijenos puta mape",
- "Upload_file_description": "Opis fajla",
"Upload_file_name": "Ime fajla",
"Upload_file_question": "Prenesi datoteku?",
"Upload_user_avatar": "Učitaj avatar",
diff --git a/packages/i18n/src/locales/ca.i18n.json b/packages/i18n/src/locales/ca.i18n.json
index 157c26d70204b..bcf860d888ee4 100644
--- a/packages/i18n/src/locales/ca.i18n.json
+++ b/packages/i18n/src/locales/ca.i18n.json
@@ -3727,7 +3727,6 @@
"Upload_Folder_Path": "Carregar ruta de la carpeta",
"Upload_From": "Pujar des de {{name}}",
"Upload_app": "Pujar l'Aplicació",
- "Upload_file_description": "Descripció de l'arxiu",
"Upload_file_name": "Nom de l'arxiu",
"Upload_file_question": "Pujar l'arxiu?",
"Upload_user_avatar": "Carregar l'avatar",
diff --git a/packages/i18n/src/locales/cs.i18n.json b/packages/i18n/src/locales/cs.i18n.json
index 565d2e6ce1cca..12a1f107c94f8 100644
--- a/packages/i18n/src/locales/cs.i18n.json
+++ b/packages/i18n/src/locales/cs.i18n.json
@@ -3157,7 +3157,6 @@
"Upload_Folder_Path": "Cesta složky pro nahrávání souborů",
"Upload_From": "Nahrát z {{name}}",
"Upload_app": "Nahrát aplikaci",
- "Upload_file_description": "Popis souboru",
"Upload_file_name": "Název souboru",
"Upload_file_question": "Nahrát soubor?",
"Upload_user_avatar": "Nahrát avatara",
diff --git a/packages/i18n/src/locales/cy.i18n.json b/packages/i18n/src/locales/cy.i18n.json
index 626e01f117d27..6d38576daade3 100644
--- a/packages/i18n/src/locales/cy.i18n.json
+++ b/packages/i18n/src/locales/cy.i18n.json
@@ -2170,7 +2170,6 @@
"Updated_at": "Wedi'i ddiweddaru yn",
"UpgradeToGetMore_engagement-dashboard_Title": "Dadansoddiadau",
"Upload_Folder_Path": "Llwytho Llwybr Ffolder",
- "Upload_file_description": "Disgrifiad o'r ffeil",
"Upload_file_name": "Ffeil enw",
"Upload_file_question": "Llwytho ffeil?",
"Upload_user_avatar": "Upload avatar",
diff --git a/packages/i18n/src/locales/da.i18n.json b/packages/i18n/src/locales/da.i18n.json
index 33be9191592b4..48b243eba896e 100644
--- a/packages/i18n/src/locales/da.i18n.json
+++ b/packages/i18n/src/locales/da.i18n.json
@@ -3251,7 +3251,6 @@
"Upload_Folder_Path": "Upload mappepath",
"Upload_From": "Upload fra {{name}}",
"Upload_app": "Upload-app",
- "Upload_file_description": "Filbeskrivelse",
"Upload_file_name": "Filnavn",
"Upload_file_question": "Upload fil?",
"Upload_user_avatar": "Upload avatar",
diff --git a/packages/i18n/src/locales/de-AT.i18n.json b/packages/i18n/src/locales/de-AT.i18n.json
index a90b74a576025..6a6d986f4ded2 100644
--- a/packages/i18n/src/locales/de-AT.i18n.json
+++ b/packages/i18n/src/locales/de-AT.i18n.json
@@ -2176,7 +2176,6 @@
"Updated_at": "Aktualisiert am",
"UpgradeToGetMore_engagement-dashboard_Title": "Analytics",
"Upload_Folder_Path": "Ordnerpfad hochladen",
- "Upload_file_description": "Dateibeschreibung",
"Upload_file_name": "Dateiname",
"Upload_file_question": "Möchten Sie eine Datei hochladen?",
"Upload_user_avatar": "Hochladen von Avataren",
diff --git a/packages/i18n/src/locales/de-IN.i18n.json b/packages/i18n/src/locales/de-IN.i18n.json
index b110b2ec4e8bc..79f6cdc9fc520 100644
--- a/packages/i18n/src/locales/de-IN.i18n.json
+++ b/packages/i18n/src/locales/de-IN.i18n.json
@@ -2449,7 +2449,6 @@
"Upload_Folder_Path": "Pfad des Uploads",
"Upload_From": "Upload von {{name}}",
"Upload_app": "App hochladen",
- "Upload_file_description": "Dateibeschreibung",
"Upload_file_name": "Dateiname",
"Upload_file_question": "Datei hochladen?",
"Upload_user_avatar": "Avatar hochladen",
diff --git a/packages/i18n/src/locales/de.i18n.json b/packages/i18n/src/locales/de.i18n.json
index 4d916bf4000c1..a89c297ee4874 100644
--- a/packages/i18n/src/locales/de.i18n.json
+++ b/packages/i18n/src/locales/de.i18n.json
@@ -4221,7 +4221,6 @@
"Upload_Folder_Path": "Pfad des Uploads",
"Upload_From": "Upload von {{name}}",
"Upload_app": "App hochladen",
- "Upload_file_description": "Dateibeschreibung",
"Upload_file_name": "Dateiname",
"Upload_file_question": "Datei hochladen?",
"Upload_user_avatar": "Avatar hochladen",
diff --git a/packages/i18n/src/locales/el.i18n.json b/packages/i18n/src/locales/el.i18n.json
index 59cdad3007b2d..29e4ca9225c21 100644
--- a/packages/i18n/src/locales/el.i18n.json
+++ b/packages/i18n/src/locales/el.i18n.json
@@ -2178,7 +2178,6 @@
"Updated_at": "Ενημερώθηκε στο",
"UpgradeToGetMore_engagement-dashboard_Title": "Αναλυτικά στοιχεία",
"Upload_Folder_Path": "Μεταφόρτωση διαδρομής φακέλου",
- "Upload_file_description": "Περιγραφή Αρχείου",
"Upload_file_name": "Ονομα αρχείου",
"Upload_file_question": "Να ανέβει το αρχείο;",
"Upload_user_avatar": "Ανεβάστε το avatar",
diff --git a/packages/i18n/src/locales/en.i18n.json b/packages/i18n/src/locales/en.i18n.json
index 82967fddf1acb..c91d77b4cd8b7 100644
--- a/packages/i18n/src/locales/en.i18n.json
+++ b/packages/i18n/src/locales/en.i18n.json
@@ -1037,7 +1037,6 @@
"Cannot_invite_users_to_direct_rooms": "Cannot invite users to direct rooms",
"Cannot_open_conversation_with_yourself": "Cannot Direct Message with yourself",
"Cannot_share_your_location": "Cannot share your location...",
- "Cannot_upload_file_character_limit": "Cannot upload file, description is over the {{count}} character limit",
"Cant_join": "Can't join",
"Categories": "Categories",
"Categories*": "Categories*",
@@ -2066,6 +2065,7 @@
"Entertainment": "Entertainment",
"Error": "Error",
"Error_404": "Error:404",
+ "Error_encrypting_file": "Error while encrypting file",
"Error_RocketChat_requires_oplog_tailing_when_running_in_multiple_instances": "Error: Rocket.Chat requires oplog tailing when running in multiple instances",
"Error_RocketChat_requires_oplog_tailing_when_running_in_multiple_instances_details": "Please make sure your MongoDB is on ReplicaSet mode and MONGO_OPLOG_URL environment variable is defined correctly on the application server",
"Error_Site_URL": "Invalid Site_Url",
@@ -2275,6 +2275,8 @@
"FileUpload_Error": "File Upload Error",
"FileUpload_FileSystemPath": "System Path",
"FileUpload_File_Empty": "File empty",
+ "FileUpload_Canceled": "Upload canceled",
+ "FileUpload_Update_Failed": "Could not update file name",
"FileUpload_GoogleStorage_AccessId": "Google Storage Access Id",
"FileUpload_GoogleStorage_AccessId_Description": "The Access Id is generally in an email format, for example: \"`example-test@example.iam.gserviceaccount.com`\"",
"FileUpload_GoogleStorage_Bucket": "Google Storage Bucket Name",
@@ -4793,6 +4795,7 @@
"Self_managed_hosting": "Self-managed hosting",
"Send": "Send",
"Send_Email_SMTP_Warning": "Set up the SMTP server in email settings to enable.",
+ "Send_anyway": "Send anyway",
"Send_Test": "Send Test",
"Send_Test_Email": "Send test email",
"Send_Visitor_navigation_history_as_a_message": "Send Visitor Navigation History as a Message",
@@ -5529,18 +5532,21 @@
"Upgrade_tab_upgrade_your_plan": "Upgrade your plan",
"Upgrade_to_Pro": "Upgrade to Pro",
"Upload": "Upload",
+ "Upload_failed": "Upload failed",
"Upload_Folder_Path": "Upload Folder Path",
"Upload_From": "Upload from {{name}}",
"Upload_anyway": "Upload anyway",
"Upload_app": "Upload App",
"Upload_file": "Upload file",
- "Upload_file_description": "File description",
"Upload_file_name": "File name",
"Upload_file_question": "Upload file?",
"Upload_private_app": "Upload private app",
"Upload_user_avatar": "Upload avatar",
"Uploading_file": "Uploading file...",
- "Uploading_file__fileName__": "Uploading file {{fileName}}",
+ "Uploading__count__file": {
+ "one": "Uploading {{count}} file",
+ "other": "Uploading {{count}} files"
+ },
"Uploads": "Uploads",
"Uptime": "Uptime",
"Usage": "Usage",
@@ -5906,6 +5912,7 @@
"You_can_do_from_account_preferences": "You can do this later from your account preferences",
"You_can_search_using_RegExp_eg": "You can search using Regular Expression. e.g. /^text$/i",
"You_can_try_to": "You can try to",
+ "You_cant_upload_more_than__count__files": "You can't upload more than {{count}} files at once.",
"You_can_use_an_emoji_as_avatar": "You can also use an emoji as an avatar.",
"You_can_use_webhooks_to_easily_integrate_livechat_with_your_CRM": "You can use webhooks to easily integrate Omnichannel with your CRM.",
"You_cant_leave_a_livechat_room_Please_use_the_close_button": "You can't leave a omnichannel room. Please, use the close button.",
@@ -6323,6 +6330,7 @@
"error-token-already-exists": "A token with this name already exists",
"error-token-does-not-exists": "Token does not exists",
"error-too-many-requests": "Error, too many requests. Please slow down. You must wait {{seconds}} seconds before trying again.",
+ "error-too-many-files": "Number of files attached to the message is over the limit.",
"error-transcript-already-requested": "Transcript already requested",
"error-unable-to-update-priority": "Unable to update priority",
"error-unknown-contact": "Contact is unknown.",
@@ -7057,6 +7065,10 @@
"one": "{{count}} file pruned",
"other": "{{count}} files pruned"
},
+ "__count__files_failed_to_upload": {
+ "one": "One file failed to upload and will not be sent: {{name}}",
+ "other": "{{count}} files failed to upload and will not be sent."
+ },
"__count__follower": {
"one": "+{{count}} follower",
"other": "+{{count}} followers"
diff --git a/packages/i18n/src/locales/eo.i18n.json b/packages/i18n/src/locales/eo.i18n.json
index 15e3e3e989af6..54f1bf1e55de1 100644
--- a/packages/i18n/src/locales/eo.i18n.json
+++ b/packages/i18n/src/locales/eo.i18n.json
@@ -2173,7 +2173,6 @@
"Updated_at": "Ĝisdatigita je",
"UpgradeToGetMore_engagement-dashboard_Title": "Analitiko",
"Upload_Folder_Path": "Alŝuti dosierujon",
- "Upload_file_description": "Dosiero priskribo",
"Upload_file_name": "Dosiernomo",
"Upload_file_question": "Alŝutu dosieron?",
"Upload_user_avatar": "Alŝuti avataron",
diff --git a/packages/i18n/src/locales/es.i18n.json b/packages/i18n/src/locales/es.i18n.json
index de62f59c85f4f..f16422bcaacc8 100644
--- a/packages/i18n/src/locales/es.i18n.json
+++ b/packages/i18n/src/locales/es.i18n.json
@@ -3935,7 +3935,6 @@
"Upload_Folder_Path": "Ruta de carpeta de subida",
"Upload_From": "Subir desde {{name}}",
"Upload_app": "Subir aplicación",
- "Upload_file_description": "Descripción de archivo",
"Upload_file_name": "Nombre de archivo",
"Upload_file_question": "¿Subir archivo?",
"Upload_user_avatar": "Subir avatar",
diff --git a/packages/i18n/src/locales/fa.i18n.json b/packages/i18n/src/locales/fa.i18n.json
index 5697d1acabdce..3679c67566457 100644
--- a/packages/i18n/src/locales/fa.i18n.json
+++ b/packages/i18n/src/locales/fa.i18n.json
@@ -2460,7 +2460,6 @@
"Updated_at": "به روز شده در",
"UpgradeToGetMore_engagement-dashboard_Title": "تجزیه و تحلیل ترافیک",
"Upload_Folder_Path": "مسیر پوشه آپلود",
- "Upload_file_description": "توضیحات فایل",
"Upload_file_name": "نام فایل",
"Upload_file_question": "آپلود فایل؟",
"Upload_user_avatar": "بارگذاری تصویر",
diff --git a/packages/i18n/src/locales/fi.i18n.json b/packages/i18n/src/locales/fi.i18n.json
index a9b822cb72709..e5849b20c895c 100644
--- a/packages/i18n/src/locales/fi.i18n.json
+++ b/packages/i18n/src/locales/fi.i18n.json
@@ -4378,7 +4378,6 @@
"Upload_From": "Lataukset käyttäjältä {{name}}",
"Upload_anyway": "Lataa silti",
"Upload_app": "Lataa sovellus",
- "Upload_file_description": "Tiedoston kuvaus",
"Upload_file_name": "Tiedoston nimi",
"Upload_file_question": "Ladataanko tiedosto?",
"Upload_private_app": "Lataa yksityinen sovellus",
diff --git a/packages/i18n/src/locales/fr.i18n.json b/packages/i18n/src/locales/fr.i18n.json
index f35809160ff9a..c3a712d08ba10 100644
--- a/packages/i18n/src/locales/fr.i18n.json
+++ b/packages/i18n/src/locales/fr.i18n.json
@@ -3815,7 +3815,6 @@
"Upload_Folder_Path": "Chemin du dossier de chargement",
"Upload_From": "Charger depuis {{name}}",
"Upload_app": "Charger l'application",
- "Upload_file_description": "Description du fichier",
"Upload_file_name": "Nom du fichier",
"Upload_file_question": "Charger le fichier ?",
"Upload_user_avatar": "Charger un avatar",
diff --git a/packages/i18n/src/locales/he.i18n.json b/packages/i18n/src/locales/he.i18n.json
index 0238794894bfe..b40bb6a3771e7 100644
--- a/packages/i18n/src/locales/he.i18n.json
+++ b/packages/i18n/src/locales/he.i18n.json
@@ -1217,7 +1217,6 @@
"Updated_at": "עודכן ב",
"UpgradeToGetMore_engagement-dashboard_Title": "סטטיסטיקה",
"Upload": "העלאה",
- "Upload_file_description": "תיאור קובץ",
"Upload_file_name": "שם קובץ",
"Upload_file_question": "להעלות קובץ?",
"Uploading_file": "מעלה קובץ...",
diff --git a/packages/i18n/src/locales/hi-IN.i18n.json b/packages/i18n/src/locales/hi-IN.i18n.json
index ed95662f37bf5..a4002206d36b5 100644
--- a/packages/i18n/src/locales/hi-IN.i18n.json
+++ b/packages/i18n/src/locales/hi-IN.i18n.json
@@ -4684,7 +4684,6 @@
"Upload_From": "{{name}} से अपलोड करें",
"Upload_anyway": "फिर भी अपलोड करें",
"Upload_app": "ऐप अपलोड करें",
- "Upload_file_description": "फाइल विवरण",
"Upload_file_name": "फ़ाइल का नाम",
"Upload_file_question": "दस्तावेज अपलोड करें?",
"Upload_private_app": "निजी ऐप अपलोड करें",
diff --git a/packages/i18n/src/locales/hr.i18n.json b/packages/i18n/src/locales/hr.i18n.json
index 44193eea1571b..4ddf9275ab148 100644
--- a/packages/i18n/src/locales/hr.i18n.json
+++ b/packages/i18n/src/locales/hr.i18n.json
@@ -2293,7 +2293,6 @@
"Updated_at": "Ažurirano u",
"UpgradeToGetMore_engagement-dashboard_Title": "Analitika",
"Upload_Folder_Path": "Prijenos puta mape",
- "Upload_file_description": "Opis fajla",
"Upload_file_name": "Ime fajla",
"Upload_file_question": "Prenesi datoteku?",
"Upload_user_avatar": "Učitaj avatar",
diff --git a/packages/i18n/src/locales/hu.i18n.json b/packages/i18n/src/locales/hu.i18n.json
index ecf9204511116..f517ea946834c 100644
--- a/packages/i18n/src/locales/hu.i18n.json
+++ b/packages/i18n/src/locales/hu.i18n.json
@@ -4115,7 +4115,6 @@
"Upload_Folder_Path": "Feltöltési mappa útvonala",
"Upload_From": "Feltöltés innen: {{name}}",
"Upload_app": "Alkalmazás feltöltése",
- "Upload_file_description": "Fájl leírása",
"Upload_file_name": "Fájlnév",
"Upload_file_question": "Feltölti a fájlt?",
"Upload_user_avatar": "Profilkép feltöltése",
diff --git a/packages/i18n/src/locales/id.i18n.json b/packages/i18n/src/locales/id.i18n.json
index c1de975661fa7..facac25d7069c 100644
--- a/packages/i18n/src/locales/id.i18n.json
+++ b/packages/i18n/src/locales/id.i18n.json
@@ -2171,7 +2171,6 @@
"Updated_at": "Diperbarui pada",
"UpgradeToGetMore_engagement-dashboard_Title": "Analytics",
"Upload_Folder_Path": "Unggah Jalur Folder",
- "Upload_file_description": "Deskripsi berkas",
"Upload_file_name": "Nama file",
"Upload_file_question": "Unggah file?",
"Upload_user_avatar": "Upload avatar",
diff --git a/packages/i18n/src/locales/it.i18n.json b/packages/i18n/src/locales/it.i18n.json
index a2aa1e70778e7..16b09bf3ddad2 100644
--- a/packages/i18n/src/locales/it.i18n.json
+++ b/packages/i18n/src/locales/it.i18n.json
@@ -2689,7 +2689,6 @@
"UpgradeToGetMore_custom-roles_Title": "Ruoli personalizzati",
"UpgradeToGetMore_engagement-dashboard_Title": "Analytics",
"Upload_Folder_Path": "Carica percorso cartella",
- "Upload_file_description": "Descrizione file",
"Upload_file_name": "Nome file",
"Upload_file_question": "Caricare il file?",
"Upload_user_avatar": "Carica avatar",
diff --git a/packages/i18n/src/locales/ja.i18n.json b/packages/i18n/src/locales/ja.i18n.json
index f0f6386b07f59..fea01bd07f297 100644
--- a/packages/i18n/src/locales/ja.i18n.json
+++ b/packages/i18n/src/locales/ja.i18n.json
@@ -3774,7 +3774,6 @@
"Upload_Folder_Path": "フォルダパスのアップロード",
"Upload_From": "{{name}}からアップロード",
"Upload_app": "アプリのアップロード",
- "Upload_file_description": "ファイルの説明",
"Upload_file_name": "ファイル名",
"Upload_file_question": "ファイルをアップロードしますか?",
"Upload_user_avatar": "アバターをアップロード",
diff --git a/packages/i18n/src/locales/ka-GE.i18n.json b/packages/i18n/src/locales/ka-GE.i18n.json
index 0a2fa1ee47d52..d206f5a4bfd80 100644
--- a/packages/i18n/src/locales/ka-GE.i18n.json
+++ b/packages/i18n/src/locales/ka-GE.i18n.json
@@ -2940,7 +2940,6 @@
"Upload_Folder_Path": "საქაღალდის გზის ატვირთვა",
"Upload_From": "ატვირთვა {{name}}",
"Upload_app": "აპლიკაციის ატვირთვა",
- "Upload_file_description": "ფაილის აღწერა",
"Upload_file_name": "ფაილის სახელი",
"Upload_file_question": "გსურთ ატვირთოთ ფაილი?",
"Upload_user_avatar": "ავატარის ატვირთვა",
diff --git a/packages/i18n/src/locales/km.i18n.json b/packages/i18n/src/locales/km.i18n.json
index 551f897ca67cf..88decac3a1631 100644
--- a/packages/i18n/src/locales/km.i18n.json
+++ b/packages/i18n/src/locales/km.i18n.json
@@ -2474,7 +2474,6 @@
"UpgradeToGetMore_engagement-dashboard_Title": "វិភាគ",
"Upload_Folder_Path": "ផ្ទុកផ្លូវថតឡើង",
"Upload_From": "ផ្ទុកឡើងពី {{name}}",
- "Upload_file_description": "ការពិពណ៌នាឯកសារ",
"Upload_file_name": "ឈ្មោះឯកសារ",
"Upload_file_question": "ផ្ទុកឯកសារឡើងឬ?",
"Upload_user_avatar": "ផ្ទុករូបតំនាង",
diff --git a/packages/i18n/src/locales/ko.i18n.json b/packages/i18n/src/locales/ko.i18n.json
index b831726de9664..8ad834a9ffcee 100644
--- a/packages/i18n/src/locales/ko.i18n.json
+++ b/packages/i18n/src/locales/ko.i18n.json
@@ -3223,7 +3223,6 @@
"Upload_Folder_Path": "폴더 경로 업로드",
"Upload_From": " {{name}} 에서 업로드",
"Upload_app": "앱 업로드",
- "Upload_file_description": "파일 설명",
"Upload_file_name": "파일 이름",
"Upload_file_question": "파일을 업로드하시겠습니까?",
"Upload_user_avatar": "아바타 업로드",
diff --git a/packages/i18n/src/locales/ku.i18n.json b/packages/i18n/src/locales/ku.i18n.json
index 50ffa0b9c9fe6..c467f5323b86f 100644
--- a/packages/i18n/src/locales/ku.i18n.json
+++ b/packages/i18n/src/locales/ku.i18n.json
@@ -2167,7 +2167,6 @@
"Updated_at": "Nûvekirî",
"UpgradeToGetMore_engagement-dashboard_Title": "analytics",
"Upload_Folder_Path": "Peldanka Peldanka Hilbijêre",
- "Upload_file_description": "Pirtûka pelê",
"Upload_file_name": "Navê pelê",
"Upload_file_question": "Pelê bar bike?",
"Upload_user_avatar": "Avatar hilbijêre",
diff --git a/packages/i18n/src/locales/lo.i18n.json b/packages/i18n/src/locales/lo.i18n.json
index fae47bb89f4c6..2af8401d90444 100644
--- a/packages/i18n/src/locales/lo.i18n.json
+++ b/packages/i18n/src/locales/lo.i18n.json
@@ -2200,7 +2200,6 @@
"Updated_at": "Updated at",
"UpgradeToGetMore_engagement-dashboard_Title": "ການວິເຄາະ",
"Upload_Folder_Path": "ອັບໂຫລດໂຟເດີໂຟເດີ",
- "Upload_file_description": "ລາຍລະອຽດຂອງໄຟລ໌",
"Upload_file_name": "ຊື່ເອກະສານ",
"Upload_file_question": "ອັບໂຫລດເອກະສານ?",
"Upload_user_avatar": "ອັບໂຫລດ avatar",
diff --git a/packages/i18n/src/locales/lt.i18n.json b/packages/i18n/src/locales/lt.i18n.json
index e9caec230cf7d..26c77c84ab205 100644
--- a/packages/i18n/src/locales/lt.i18n.json
+++ b/packages/i18n/src/locales/lt.i18n.json
@@ -2225,7 +2225,6 @@
"Updated_at": "Atnaujinta",
"UpgradeToGetMore_engagement-dashboard_Title": "\"Analytics\"",
"Upload_Folder_Path": "Įkelti aplanko kelią",
- "Upload_file_description": "Failo aprašymas",
"Upload_file_name": "Failo pavadinimas",
"Upload_file_question": "Įkelti failą?",
"Upload_user_avatar": "Įkelti avatarą",
diff --git a/packages/i18n/src/locales/lv.i18n.json b/packages/i18n/src/locales/lv.i18n.json
index fbf1c9d03bd66..99161e3f78d6b 100644
--- a/packages/i18n/src/locales/lv.i18n.json
+++ b/packages/i18n/src/locales/lv.i18n.json
@@ -2185,7 +2185,6 @@
"Updated_at": "Atjaunināts uz",
"UpgradeToGetMore_engagement-dashboard_Title": "Analītika",
"Upload_Folder_Path": "Augšupielādēt mapes ceļu",
- "Upload_file_description": "Faila apraksts",
"Upload_file_name": "Faila nosaukums",
"Upload_file_question": "Vai augšupielādēt failu?",
"Upload_user_avatar": "Augšupielādēt avataru",
diff --git a/packages/i18n/src/locales/mn.i18n.json b/packages/i18n/src/locales/mn.i18n.json
index 72c04332a5c36..0038b53ac8705 100644
--- a/packages/i18n/src/locales/mn.i18n.json
+++ b/packages/i18n/src/locales/mn.i18n.json
@@ -2171,7 +2171,6 @@
"Updated_at": "Дээр шинэчилсэн",
"UpgradeToGetMore_engagement-dashboard_Title": "Аналитик",
"Upload_Folder_Path": "Folder Path-г оруулна уу",
- "Upload_file_description": "Файлын тайлбар",
"Upload_file_name": "Файлын нэр",
"Upload_file_question": "Файл оруулах уу?",
"Upload_user_avatar": "Зургийг байршуулна уу",
diff --git a/packages/i18n/src/locales/ms-MY.i18n.json b/packages/i18n/src/locales/ms-MY.i18n.json
index 1aadb5f2e7dd0..1350515fab24c 100644
--- a/packages/i18n/src/locales/ms-MY.i18n.json
+++ b/packages/i18n/src/locales/ms-MY.i18n.json
@@ -2177,7 +2177,6 @@
"Updated_at": "Dikemaskini di",
"UpgradeToGetMore_engagement-dashboard_Title": "Analisis",
"Upload_Folder_Path": "Muatkan Laluan Folder",
- "Upload_file_description": "Penerangan fail",
"Upload_file_name": "Nama fail",
"Upload_file_question": "Muat naik fail?",
"Upload_user_avatar": "Muat naik avatar",
diff --git a/packages/i18n/src/locales/nb.i18n.json b/packages/i18n/src/locales/nb.i18n.json
index caa6d826b9277..ec3ed6cfa82de 100644
--- a/packages/i18n/src/locales/nb.i18n.json
+++ b/packages/i18n/src/locales/nb.i18n.json
@@ -940,7 +940,6 @@
"Cannot_invite_users_to_direct_rooms": "Kan ikke invitere brukere til direkterom",
"Cannot_open_conversation_with_yourself": "Kan ikke sende direkte-melding til deg selv",
"Cannot_share_your_location": "Kan ikke dele din posisjonen...",
- "Cannot_upload_file_character_limit": "Kan ikke laste opp filen, beskrivelsen overskrider {{count}} tegn",
"Cant_join": "Kan ikke bli med",
"Categories": "Kategorier",
"Categories*": "Kategorier*",
@@ -5382,13 +5381,11 @@
"Upload_anyway": "Last opp allikevel",
"Upload_app": "Last opp app",
"Upload_file": "Last opp fil",
- "Upload_file_description": "Filbeskrivelse",
"Upload_file_name": "Filnavn",
"Upload_file_question": "Laste opp fil?",
"Upload_private_app": "Last opp privat app",
"Upload_user_avatar": "Last opp avatar",
"Uploading_file": "Laster opp fil ...",
- "Uploading_file__fileName__": "Laste opp fil {{fileName}}",
"Uploads": "Opplastinger",
"Uptime": "Oppetid",
"Usage": "Bruk",
diff --git a/packages/i18n/src/locales/nl.i18n.json b/packages/i18n/src/locales/nl.i18n.json
index 814f4045fc636..46f1cc2e4dfcb 100644
--- a/packages/i18n/src/locales/nl.i18n.json
+++ b/packages/i18n/src/locales/nl.i18n.json
@@ -3803,7 +3803,6 @@
"Upload_Folder_Path": "Upload mappad",
"Upload_From": "Uploaden van {{name}}",
"Upload_app": "App uploaden",
- "Upload_file_description": "Bestandsomschrijving",
"Upload_file_name": "Bestandsnaam",
"Upload_file_question": "Upload bestand?",
"Upload_user_avatar": "Upload avatar",
diff --git a/packages/i18n/src/locales/nn.i18n.json b/packages/i18n/src/locales/nn.i18n.json
index cf5a888534793..0b5616ff6785d 100644
--- a/packages/i18n/src/locales/nn.i18n.json
+++ b/packages/i18n/src/locales/nn.i18n.json
@@ -914,7 +914,6 @@
"Cannot_invite_users_to_direct_rooms": "Kan ikke invitere brukere til å lede rom",
"Cannot_open_conversation_with_yourself": "Kan ikke sende melding til deg selv",
"Cannot_share_your_location": "Kan ikke dele din posisjonen...",
- "Cannot_upload_file_character_limit": "Kan ikke laste opp filen, beskrivelsen overskrider {{count}} tegn",
"Cant_join": "Kan ikke bli med",
"Categories": "Kategorier",
"Categories*": "Kategorier*",
@@ -4923,7 +4922,6 @@
"Upload_anyway": "Last opp allikevel",
"Upload_app": "Last opp app",
"Upload_file": "Last opp fil",
- "Upload_file_description": "Filbeskrivelse",
"Upload_file_name": "Filnavn",
"Upload_file_question": "Last opp fil?",
"Upload_private_app": "Last opp privat app",
diff --git a/packages/i18n/src/locales/pl.i18n.json b/packages/i18n/src/locales/pl.i18n.json
index f92eb518535ad..2e6516f49a60e 100644
--- a/packages/i18n/src/locales/pl.i18n.json
+++ b/packages/i18n/src/locales/pl.i18n.json
@@ -4124,7 +4124,6 @@
"Upload_Folder_Path": "Prześlij ścieżkę folderu",
"Upload_From": "Prześlij z {{name}}",
"Upload_app": "Prześlij aplikację",
- "Upload_file_description": "Opis pliku",
"Upload_file_name": "Nazwa pliku",
"Upload_file_question": "Przesłać plik?",
"Upload_user_avatar": "Załaduj awatar",
diff --git a/packages/i18n/src/locales/pt-BR.i18n.json b/packages/i18n/src/locales/pt-BR.i18n.json
index bb0fcd949a94c..76c6617598bae 100644
--- a/packages/i18n/src/locales/pt-BR.i18n.json
+++ b/packages/i18n/src/locales/pt-BR.i18n.json
@@ -933,7 +933,6 @@
"Cannot_invite_users_to_direct_rooms": "Não é possível convidar pessoas para salas diretas",
"Cannot_open_conversation_with_yourself": "Não é possível dirigir a mensagem com você mesmo",
"Cannot_share_your_location": "Não foi possível compartilhar sua localização...",
- "Cannot_upload_file_character_limit": "Não é possível fazer upload de arquivo, a descrição está acima do limite de caracteres {{count}} ",
"Cant_join": "Não é possível participar",
"Categories": "Categorias",
"Categories*": "Categorias*",
@@ -5261,7 +5260,6 @@
"Upload_anyway": "Fazer upload de qualquer forma",
"Upload_app": "Upload de aplicativo",
"Upload_file": "Carregar arquivo",
- "Upload_file_description": "Descrição do arquivo",
"Upload_file_name": "Nome do arquivo",
"Upload_file_question": "Fazer upload de arquivo?",
"Upload_private_app": "Carregar aplicativo privado",
diff --git a/packages/i18n/src/locales/pt.i18n.json b/packages/i18n/src/locales/pt.i18n.json
index d77fa3919e2d3..747663407d5fa 100644
--- a/packages/i18n/src/locales/pt.i18n.json
+++ b/packages/i18n/src/locales/pt.i18n.json
@@ -2515,7 +2515,6 @@
"UpgradeToGetMore_engagement-dashboard_Title": "Analytics",
"Upload_Folder_Path": "Carregar caminho da pasta",
"Upload_From": "Upload de {{name}}",
- "Upload_file_description": "Descrição do ficheiro",
"Upload_file_name": "Nome do ficheiro",
"Upload_file_question": "Carregar ficheiro?",
"Upload_user_avatar": "Carregar Avatar",
diff --git a/packages/i18n/src/locales/ro.i18n.json b/packages/i18n/src/locales/ro.i18n.json
index 5a9b0e35be816..8f0ac8dba714f 100644
--- a/packages/i18n/src/locales/ro.i18n.json
+++ b/packages/i18n/src/locales/ro.i18n.json
@@ -2174,7 +2174,6 @@
"Updated_at": "Actualizat la",
"UpgradeToGetMore_engagement-dashboard_Title": "Analytics",
"Upload_Folder_Path": "Încărcați calea folderelor",
- "Upload_file_description": "Descrierea fisierului",
"Upload_file_name": "Nume de fișier",
"Upload_file_question": "Încarcă fișier?",
"Upload_user_avatar": "Încărcați avatar",
diff --git a/packages/i18n/src/locales/ru.i18n.json b/packages/i18n/src/locales/ru.i18n.json
index 7f19415d8c359..902658f65a3df 100644
--- a/packages/i18n/src/locales/ru.i18n.json
+++ b/packages/i18n/src/locales/ru.i18n.json
@@ -3957,7 +3957,6 @@
"Upload_Folder_Path": "Путь к папке загрузки",
"Upload_From": "Загрузить с {{name}}",
"Upload_app": "Загрузить приложение",
- "Upload_file_description": "Описание файла",
"Upload_file_name": "Имя файла",
"Upload_file_question": "Загрузить файл?",
"Upload_user_avatar": "Загруженный аватар",
diff --git a/packages/i18n/src/locales/sk-SK.i18n.json b/packages/i18n/src/locales/sk-SK.i18n.json
index 68a9eb0284f57..bc4ad81b8ba2a 100644
--- a/packages/i18n/src/locales/sk-SK.i18n.json
+++ b/packages/i18n/src/locales/sk-SK.i18n.json
@@ -2179,7 +2179,6 @@
"Updated_at": "Aktualizované na",
"UpgradeToGetMore_engagement-dashboard_Title": "Analytika",
"Upload_Folder_Path": "Nahrať cestu priečinka",
- "Upload_file_description": "Popis súboru",
"Upload_file_name": "Názov súboru",
"Upload_file_question": "Nahrajte súbor?",
"Upload_user_avatar": "Nahrať avatar",
diff --git a/packages/i18n/src/locales/sl-SI.i18n.json b/packages/i18n/src/locales/sl-SI.i18n.json
index d4e3e956dda58..fb738e0282d44 100644
--- a/packages/i18n/src/locales/sl-SI.i18n.json
+++ b/packages/i18n/src/locales/sl-SI.i18n.json
@@ -2171,7 +2171,6 @@
"Updated_at": "Posodobljeno ob",
"UpgradeToGetMore_engagement-dashboard_Title": "Analiza",
"Upload_Folder_Path": "Naloži pot do mape",
- "Upload_file_description": "Opis datoteke",
"Upload_file_name": "Ime datoteke",
"Upload_file_question": "Želite naložiti datoteko?",
"Upload_user_avatar": "Naloži avatar",
diff --git a/packages/i18n/src/locales/sq.i18n.json b/packages/i18n/src/locales/sq.i18n.json
index e9282747915d6..79d83c53c7664 100644
--- a/packages/i18n/src/locales/sq.i18n.json
+++ b/packages/i18n/src/locales/sq.i18n.json
@@ -2175,7 +2175,6 @@
"Updated_at": "Përditësuar në",
"UpgradeToGetMore_engagement-dashboard_Title": "Analitikë",
"Upload_Folder_Path": "Ngarko dosjen e dosjes",
- "Upload_file_description": "Përshkrimi i skedarit",
"Upload_file_name": "Emri i skedarit",
"Upload_file_question": "Ngarko skedar?",
"Upload_user_avatar": "Ngarko avatar",
diff --git a/packages/i18n/src/locales/sr.i18n.json b/packages/i18n/src/locales/sr.i18n.json
index 931fba1cb698c..323697438cab3 100644
--- a/packages/i18n/src/locales/sr.i18n.json
+++ b/packages/i18n/src/locales/sr.i18n.json
@@ -2009,7 +2009,6 @@
"Updated_at": "Ажурирано у",
"UpgradeToGetMore_engagement-dashboard_Title": "Аналитика",
"Upload_Folder_Path": "Путања фолдера",
- "Upload_file_description": "Опис фајла",
"Upload_file_name": "Назив документа",
"Upload_file_question": "Отпреми датотеку?",
"Upload_user_avatar": "Уплоад аватар",
diff --git a/packages/i18n/src/locales/sv.i18n.json b/packages/i18n/src/locales/sv.i18n.json
index 096c327993124..e793c962f4a35 100644
--- a/packages/i18n/src/locales/sv.i18n.json
+++ b/packages/i18n/src/locales/sv.i18n.json
@@ -932,7 +932,6 @@
"Cannot_invite_users_to_direct_rooms": "Det går inte att bjuda in användare att styra rum",
"Cannot_open_conversation_with_yourself": "Kan inte skicka direktmeddelande till dig själv",
"Cannot_share_your_location": "Kan inte dela din plats...",
- "Cannot_upload_file_character_limit": "Det går inte att ladda upp filen, beskrivningen överskrider teckengränsen på {{count}} ",
"Cant_join": "Kan inte gå med",
"Categories": "Kategorier",
"Categories*": "Kategorier*",
@@ -5290,13 +5289,11 @@
"Upload_anyway": "Ladda upp ändå",
"Upload_app": "Ladda upp app",
"Upload_file": "Ladda upp fil",
- "Upload_file_description": "Filbeskrivning",
"Upload_file_name": "Filnamn",
"Upload_file_question": "Ladda upp fil?",
"Upload_private_app": "Ladda upp en privat app",
"Upload_user_avatar": "Ladda upp avatar",
"Uploading_file": "Laddar upp fil...",
- "Uploading_file__fileName__": "Ladda upp fil {{fileName}}",
"Uploads": "Uppladdningar",
"Uptime": "Upptid",
"Usage": "Användning",
diff --git a/packages/i18n/src/locales/ta-IN.i18n.json b/packages/i18n/src/locales/ta-IN.i18n.json
index 7d9181f76cafe..88bd24cfe150d 100644
--- a/packages/i18n/src/locales/ta-IN.i18n.json
+++ b/packages/i18n/src/locales/ta-IN.i18n.json
@@ -2174,7 +2174,6 @@
"Updated_at": "புதுப்பிக்கப்பட்டது",
"UpgradeToGetMore_engagement-dashboard_Title": "அனலிட்டிக்ஸ்",
"Upload_Folder_Path": "கோப்புறை பாதை பதிவேற்றவும்",
- "Upload_file_description": "கோப்பு விளக்கம்",
"Upload_file_name": "கோப்பு பெயர்",
"Upload_file_question": "கோப்பை பதிவேற்ற?",
"Upload_user_avatar": "பதிவைப் பதிவேற்று",
diff --git a/packages/i18n/src/locales/th-TH.i18n.json b/packages/i18n/src/locales/th-TH.i18n.json
index 43beb1d1fa398..ed4ddcbff76c2 100644
--- a/packages/i18n/src/locales/th-TH.i18n.json
+++ b/packages/i18n/src/locales/th-TH.i18n.json
@@ -2167,7 +2167,6 @@
"Updated_at": "อัปเดตเมื่อวันที่",
"UpgradeToGetMore_engagement-dashboard_Title": "Analytics",
"Upload_Folder_Path": "อัปโหลดเส้นทางโฟลเดอร์",
- "Upload_file_description": "คำอธิบายไฟล์",
"Upload_file_name": "ชื่อไฟล์",
"Upload_file_question": "อัปโหลดไฟล์หรือไม่?",
"Upload_user_avatar": "อัปโหลดภาพอวตาร",
diff --git a/packages/i18n/src/locales/tr.i18n.json b/packages/i18n/src/locales/tr.i18n.json
index 06e8d3364cdea..154fcd48cc378 100644
--- a/packages/i18n/src/locales/tr.i18n.json
+++ b/packages/i18n/src/locales/tr.i18n.json
@@ -2581,7 +2581,6 @@
"Upload_Folder_Path": "Dosya yükleme konumu",
"Upload_From": "{{name}} den yükle",
"Upload_app": "Uygulamayı Yükle",
- "Upload_file_description": "Dosya açıklaması",
"Upload_file_name": "Dosya adı",
"Upload_file_question": "Dosya yükle?",
"Upload_user_avatar": "Avatarı yükle",
diff --git a/packages/i18n/src/locales/uk.i18n.json b/packages/i18n/src/locales/uk.i18n.json
index 5d79695872f3c..a917a483a5b05 100644
--- a/packages/i18n/src/locales/uk.i18n.json
+++ b/packages/i18n/src/locales/uk.i18n.json
@@ -2667,7 +2667,6 @@
"UpgradeToGetMore_auditing_Title": "Аудит повідомлень",
"UpgradeToGetMore_engagement-dashboard_Title": "Аналітика",
"Upload_Folder_Path": "Завантажте шлях до папки",
- "Upload_file_description": "Опис файлу",
"Upload_file_name": "Ім'я файлу",
"Upload_file_question": "Завантажити файл?",
"Upload_user_avatar": "Завантажити аватар",
diff --git a/packages/i18n/src/locales/vi-VN.i18n.json b/packages/i18n/src/locales/vi-VN.i18n.json
index 72742c0e0f6ab..1cbf7609bbac1 100644
--- a/packages/i18n/src/locales/vi-VN.i18n.json
+++ b/packages/i18n/src/locales/vi-VN.i18n.json
@@ -2268,7 +2268,6 @@
"Updated_at": "Cập nhật tại",
"UpgradeToGetMore_engagement-dashboard_Title": "phân tích",
"Upload_Folder_Path": "Tải lên đường dẫn thư mục",
- "Upload_file_description": "Mô tả tập tin",
"Upload_file_name": "Tên tệp",
"Upload_file_question": "Cập nhật dử liệu?",
"Upload_user_avatar": "Tải lên hình đại diện",
diff --git a/packages/i18n/src/locales/zh-HK.i18n.json b/packages/i18n/src/locales/zh-HK.i18n.json
index c95a888279ae1..547d0fad75e49 100644
--- a/packages/i18n/src/locales/zh-HK.i18n.json
+++ b/packages/i18n/src/locales/zh-HK.i18n.json
@@ -2201,7 +2201,6 @@
"Updated_at": "更新于",
"UpgradeToGetMore_engagement-dashboard_Title": "分析",
"Upload_Folder_Path": "上传文件夹路径",
- "Upload_file_description": "文件描述",
"Upload_file_name": "文件名",
"Upload_file_question": "上传文件?",
"Upload_user_avatar": "上传头像",
diff --git a/packages/i18n/src/locales/zh-TW.i18n.json b/packages/i18n/src/locales/zh-TW.i18n.json
index d5d9768f7964e..560bfbfe7fd26 100644
--- a/packages/i18n/src/locales/zh-TW.i18n.json
+++ b/packages/i18n/src/locales/zh-TW.i18n.json
@@ -3602,7 +3602,6 @@
"Upload_Folder_Path": "上傳資料夾路徑",
"Upload_From": "從 {{name}} 上傳",
"Upload_app": "上傳應用程式",
- "Upload_file_description": "檔案敘述",
"Upload_file_name": "檔案名稱",
"Upload_file_question": "是否上傳檔案?",
"Upload_user_avatar": "上傳頭像",
diff --git a/packages/i18n/src/locales/zh.i18n.json b/packages/i18n/src/locales/zh.i18n.json
index a84225ff34232..9f336a437edb4 100644
--- a/packages/i18n/src/locales/zh.i18n.json
+++ b/packages/i18n/src/locales/zh.i18n.json
@@ -1030,7 +1030,6 @@
"Cannot_invite_users_to_direct_rooms": "不能邀请用户加入私聊",
"Cannot_open_conversation_with_yourself": "不能和你自己私聊",
"Cannot_share_your_location": "不能分享您的位置…",
- "Cannot_upload_file_character_limit": "无法上传文件,描述超过 {{count}} 个字符限制",
"Cant_join": "无法加入",
"Categories": "类别",
"Categories*": "类别*",
@@ -5513,13 +5512,11 @@
"Upload_anyway": "仍然上传",
"Upload_app": "上传应用",
"Upload_file": "上传文件",
- "Upload_file_description": "文件描述",
"Upload_file_name": "文件名",
"Upload_file_question": "上传文件?",
"Upload_private_app": "上传私有应用",
"Upload_user_avatar": "上传头像",
"Uploading_file": "文件上传中……",
- "Uploading_file__fileName__": "正在上传文件 {{fileName}}",
"Uploads": "上传",
"Uptime": "运行时间",
"Usage": "使用情况",
diff --git a/packages/rest-typings/src/v1/rooms.ts b/packages/rest-typings/src/v1/rooms.ts
index 97b8d483f2212..3aa1a850a746b 100644
--- a/packages/rest-typings/src/v1/rooms.ts
+++ b/packages/rest-typings/src/v1/rooms.ts
@@ -794,10 +794,14 @@ export type RoomsEndpoints = {
groupable?: boolean;
msg?: string;
tmid?: string;
- customFields?: string;
+ customFields?: Record;
t?: IMessage['t'];
content?: IE2EEMessage['content'];
- }) => { message: IMessage | null };
+ fileName?: string;
+ fileContent?: IE2EEMessage['content'];
+ }) => {
+ message: IMessage | null;
+ };
};
'/v1/rooms.nameExists': {
diff --git a/packages/ui-composer/src/MessageComposer/MessageComposer.stories.tsx b/packages/ui-composer/src/MessageComposer/MessageComposer.stories.tsx
index 3c03bed370ea0..0b6b511715cd8 100644
--- a/packages/ui-composer/src/MessageComposer/MessageComposer.stories.tsx
+++ b/packages/ui-composer/src/MessageComposer/MessageComposer.stories.tsx
@@ -1,4 +1,5 @@
-import { Button } from '@rocket.chat/fuselage';
+import { Button, IconButton } from '@rocket.chat/fuselage';
+import { action } from '@storybook/addon-actions';
import type { Meta, StoryFn } from '@storybook/react';
import '@rocket.chat/icons/dist/rocketchat.css';
@@ -13,6 +14,9 @@ import {
MessageComposerSkeleton,
MessageComposerHint,
MessageComposerInputExpandable,
+ MessageComposerFile,
+ MessageComposerFileGroup,
+ MessageComposerFileError,
} from '.';
export default {
@@ -105,4 +109,40 @@ export const WithSubmit: StoryFn = () => (
);
+export const WithFiles: StoryFn = () => (
+
+
+
+ }
+ onClick={action('click')}
+ />
+ }
+ onClick={action('click')}
+ />
+ }
+ onClick={action('click')}
+ />
+
+
+
+
+
+
+
+
+
+);
+
export const Loading: StoryFn = () => ;
diff --git a/packages/ui-composer/src/MessageComposer/MessageComposerFile/MessageComposerFile.tsx b/packages/ui-composer/src/MessageComposer/MessageComposerFile/MessageComposerFile.tsx
new file mode 100644
index 0000000000000..c812d1807c665
--- /dev/null
+++ b/packages/ui-composer/src/MessageComposer/MessageComposerFile/MessageComposerFile.tsx
@@ -0,0 +1,96 @@
+import { css } from '@rocket.chat/css-in-js';
+import { Box, Palette } from '@rocket.chat/fuselage';
+import { useButtonPattern } from '@rocket.chat/fuselage-hooks';
+import { useMemo, type KeyboardEvent, type MouseEvent, type AllHTMLAttributes, type ReactElement } from 'react';
+
+type MessageComposerFileProps = {
+ fileTitle: string;
+ fileSubtitle: string;
+ actionIcon: ReactElement;
+ error?: boolean;
+ disabled?: boolean;
+ onClick: () => void;
+} & Omit, 'is'>;
+
+const MessageComposerFile = ({
+ fileTitle,
+ fileSubtitle,
+ actionIcon,
+ error,
+ disabled,
+ onClick,
+ className,
+ ...props
+}: MessageComposerFileProps) => {
+ const closeWrapperStyle = css`
+ position: absolute;
+ right: 0.5rem;
+ top: 0.5rem;
+ `;
+
+ const previewWrapperStyle = css`
+ background-color: ${Palette.surface['surface-tint']};
+ cursor: ${error || disabled ? 'not-allowed' : 'pointer'};
+
+ &:hover {
+ background-color: ${!error && !disabled ? Palette.surface['surface-hover'] : Palette.surface['surface-tint']};
+ }
+ `;
+
+ const handleClick = (e: MouseEvent | KeyboardEvent) => {
+ e.stopPropagation();
+ if (!error && !disabled) {
+ onClick();
+ }
+ };
+
+ const buttonProps = useButtonPattern(handleClick);
+
+ const subtitleColor = useMemo(() => {
+ if (error) {
+ return 'danger';
+ }
+
+ if (disabled) {
+ return 'disabled';
+ }
+
+ return 'hint';
+ }, [disabled, error]);
+
+ return (
+
+
+
+ {fileTitle}
+
+
+ {fileSubtitle}
+
+
+ {!disabled && {actionIcon}}
+
+ );
+};
+
+export default MessageComposerFile;
diff --git a/packages/ui-composer/src/MessageComposer/MessageComposerFile/MessageComposerFileError.tsx b/packages/ui-composer/src/MessageComposer/MessageComposerFile/MessageComposerFileError.tsx
new file mode 100644
index 0000000000000..6fc5f180f758a
--- /dev/null
+++ b/packages/ui-composer/src/MessageComposer/MessageComposerFile/MessageComposerFileError.tsx
@@ -0,0 +1,29 @@
+import type { AllHTMLAttributes, ReactElement } from 'react';
+import { useTranslation } from 'react-i18next';
+
+import MessageComposerFile from './MessageComposerFile';
+
+type MessageComposerFileErrorProps = {
+ fileTitle: string;
+ error: Error;
+ actionIcon: ReactElement;
+ onClick: () => void;
+} & AllHTMLAttributes;
+
+const MessageComposerFileError = ({ fileTitle, error, actionIcon, onClick, ...props }: MessageComposerFileErrorProps) => {
+ const { t } = useTranslation();
+
+ return (
+
+ );
+};
+
+export default MessageComposerFileError;
diff --git a/packages/ui-composer/src/MessageComposer/MessageComposerFile/MessageComposerFileGroup.tsx b/packages/ui-composer/src/MessageComposer/MessageComposerFile/MessageComposerFileGroup.tsx
new file mode 100644
index 0000000000000..c745b60a1bcf2
--- /dev/null
+++ b/packages/ui-composer/src/MessageComposer/MessageComposerFile/MessageComposerFileGroup.tsx
@@ -0,0 +1,23 @@
+import { Box } from '@rocket.chat/fuselage';
+import type { ComponentProps } from 'react';
+
+const MessageComposerFileGroup = ({ children, style, ...props }: ComponentProps) => {
+ return (
+
+ {children}
+
+ );
+};
+
+export default MessageComposerFileGroup;
diff --git a/packages/ui-composer/src/MessageComposer/MessageComposerFile/MessageComposerFileLoader.tsx b/packages/ui-composer/src/MessageComposer/MessageComposerFile/MessageComposerFileLoader.tsx
new file mode 100644
index 0000000000000..ca515e3a534b8
--- /dev/null
+++ b/packages/ui-composer/src/MessageComposer/MessageComposerFile/MessageComposerFileLoader.tsx
@@ -0,0 +1,41 @@
+import { css } from '@rocket.chat/css-in-js';
+import { Box, Palette } from '@rocket.chat/fuselage';
+import type { AllHTMLAttributes } from 'react';
+
+const MessageComposerFileLoader = ({ className, ...props }: Omit, 'is'>) => {
+ const customCSS = css`
+ animation: spin-animation 0.8s linear infinite;
+
+ @keyframes spin-animation {
+ from {
+ transform: rotate(0deg);
+ }
+
+ to {
+ transform: rotate(360deg);
+ }
+ }
+ `;
+
+ return (
+
+
+
+
+ );
+};
+
+export default MessageComposerFileLoader;
diff --git a/packages/ui-composer/src/MessageComposer/MessageComposerFile/index.ts b/packages/ui-composer/src/MessageComposer/MessageComposerFile/index.ts
new file mode 100644
index 0000000000000..6414906325355
--- /dev/null
+++ b/packages/ui-composer/src/MessageComposer/MessageComposerFile/index.ts
@@ -0,0 +1,4 @@
+export { default as MessageComposerFile } from './MessageComposerFile';
+export { default as MessageComposerFileError } from './MessageComposerFileError';
+export { default as MessageComposerFileLoader } from './MessageComposerFileLoader';
+export { default as MessageComposerFileGroup } from './MessageComposerFileGroup';
diff --git a/packages/ui-composer/src/MessageComposer/MessageComposerHint.tsx b/packages/ui-composer/src/MessageComposer/MessageComposerHint.tsx
index fbb282583a6be..61f4abba70662 100644
--- a/packages/ui-composer/src/MessageComposer/MessageComposerHint.tsx
+++ b/packages/ui-composer/src/MessageComposer/MessageComposerHint.tsx
@@ -12,7 +12,7 @@ const MessageComposerHint = ({ icon, children, helperText }: MessageComposerHint
: undefined}>{children}
{helperText && (
-
+
{helperText}
)}
diff --git a/packages/ui-composer/src/MessageComposer/__snapshots__/MessageComposer.spec.tsx.snap b/packages/ui-composer/src/MessageComposer/__snapshots__/MessageComposer.spec.tsx.snap
index a6b54b51ea279..d2fdb846060ac 100644
--- a/packages/ui-composer/src/MessageComposer/__snapshots__/MessageComposer.spec.tsx.snap
+++ b/packages/ui-composer/src/MessageComposer/__snapshots__/MessageComposer.spec.tsx.snap
@@ -591,6 +591,326 @@ exports[`renders ToolbarActions without crashing 1`] = `