Merge branch 'release/rc-v1.2.0' of github.com:ONLYOFFICE/DocSpace into release/rc-v1.2.0
This commit is contained in:
commit
17a625252b
@ -24,10 +24,9 @@ map $request_uri $header_x_frame_options {
|
||||
|
||||
map $request_uri $cache_control {
|
||||
default "no-cache, no-store, no-transform";
|
||||
~*\/(filehandler\.ashx\?action=thumb.*) "must-revalidate, no-transform, immutable, max-age=31536000";
|
||||
~*\/(filehandler\.ashx\?action=thumb)|\/(storage\/room_logos\/root\/|storage\/userPhotos\/root\/) "must-revalidate, no-transform, immutable, max-age=31536000";
|
||||
~*\/(api\/2\.0.*|storage|login\.ashx|filehandler\.ashx|ChunkedUploader.ashx|ThirdPartyAppHandler|apisystem|sh|remoteEntry\.js|debuginfo\.md|static\/scripts.*) "no-cache, no-store, no-transform";
|
||||
~*\/(locales.*\.json) "must-revalidate, no-transform, max-age=900";
|
||||
~*\/(images|favicon.ico.*)|\.(js|woff|woff2|css)|\/(storage\/room_logos\/root\/|storage\/userPhotos\/root\/) "must-revalidate, no-transform, immutable, max-age=31536000";
|
||||
~*\/(images|favicon.ico.*)|\.(js|woff|woff2|css)|(locales.*\.json) "must-revalidate, no-transform, immutable, max-age=31536000";
|
||||
}
|
||||
|
||||
include /etc/nginx/includes/onlyoffice-*.conf;
|
||||
@ -114,6 +113,10 @@ server {
|
||||
try_files /plugins/$basename /index.html =404;
|
||||
}
|
||||
|
||||
location ~* /static/images/(.*)$ {
|
||||
try_files /images/$1 /index.html =404;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
location /doceditor {
|
||||
@ -128,6 +131,14 @@ server {
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
||||
location ~* /static/images/(.*)$ {
|
||||
try_files /images/$1 /index.html =404;
|
||||
}
|
||||
|
||||
location ~* /static/fonts/ {
|
||||
try_files /fonts/$basename /index.html =404;
|
||||
}
|
||||
}
|
||||
|
||||
location /login {
|
||||
@ -142,6 +153,14 @@ server {
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
||||
location ~* /static/images/(.*)$ {
|
||||
try_files /images/$1 /index.html =404;
|
||||
}
|
||||
|
||||
location ~* /static/fonts/ {
|
||||
try_files /fonts/$basename /index.html =404;
|
||||
}
|
||||
}
|
||||
|
||||
location /sockjs-node {
|
||||
|
@ -71,6 +71,7 @@
|
||||
"html-webpack-plugin": "5.3.2",
|
||||
"json-loader": "^0.5.7",
|
||||
"playwright": "^1.18.1",
|
||||
"prebuild-webpack-plugin": "^1.1.1",
|
||||
"sass": "^1.39.2",
|
||||
"sass-loader": "^12.1.0",
|
||||
"serve": "14.1.1",
|
||||
|
@ -126,7 +126,7 @@
|
||||
"PleaseNote": "Please note",
|
||||
"PleaseNoteDescription": "<0>{{pleaseNote}}</0>: your old space address will become available to new users once you click the <2>{{save}}</2> button.",
|
||||
"Plugins": "Plugins",
|
||||
"PortalAccess": "Space access",
|
||||
"PortalAccess": "Portal access",
|
||||
"PortalAccessSubTitle": "This section allows you to provide users with safe and convenient ways to access the space.",
|
||||
"PortalDeactivation": "Deactivate DocSpace",
|
||||
"PortalDeactivationDescription": "Use this option to deactivate your space temporarily.",
|
||||
|
@ -3,7 +3,9 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
|
||||
import { loadLanguagePath } from "SRC_DIR/helpers/utils";
|
||||
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
|
@ -3,8 +3,8 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
import { loadLanguagePath } from "SRC_DIR/helpers/utils";
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
newInstance
|
||||
|
@ -16,7 +16,6 @@ const DeleteDialogComponent = (props) => {
|
||||
setBufferSelection,
|
||||
setRemoveMediaItem,
|
||||
setDeleteDialogVisible,
|
||||
personal,
|
||||
visible,
|
||||
tReady,
|
||||
isLoading,
|
||||
@ -26,6 +25,8 @@ const DeleteDialogComponent = (props) => {
|
||||
isRoomDelete,
|
||||
setIsRoomDelete,
|
||||
deleteRoomsAction,
|
||||
isPersonalRoom,
|
||||
isRoom,
|
||||
} = props;
|
||||
|
||||
const selection = [];
|
||||
@ -116,40 +117,34 @@ const DeleteDialogComponent = (props) => {
|
||||
|
||||
const moveToTrashNoteText = () => {
|
||||
const isFolder = selection[0]?.isFolder || !!selection[0]?.parentId;
|
||||
const { pathname } = location;
|
||||
const isSingle = selection.length === 1;
|
||||
|
||||
if (selection.length > 1) {
|
||||
if (isRoomDelete)
|
||||
return `${t("DeleteRooms")} ${t("Common:WantToContinue")}`;
|
||||
if (isRecycleBinFolder) {
|
||||
return t("DeleteItems");
|
||||
}
|
||||
if (pathname.startsWith("/rooms/personal")) {
|
||||
return t("MoveToTrashItemsFromPersonal");
|
||||
} else if (pathname.startsWith("/rooms/shared")) {
|
||||
return t("MoveToTrashItems");
|
||||
}
|
||||
} else {
|
||||
if (isRoomDelete)
|
||||
return `${t("DeleteRoom")} ${t("Common:WantToContinue")}`;
|
||||
if (isRoomDelete) {
|
||||
return isSingle
|
||||
? `${t("DeleteRoom")} ${t("Common:WantToContinue")}`
|
||||
: `${t("DeleteRooms")} ${t("Common:WantToContinue")}`;
|
||||
}
|
||||
|
||||
if (pathname.startsWith("/rooms/personal")) {
|
||||
return !isFolder
|
||||
? t("MoveToTrashFileFromPersonal")
|
||||
: personal
|
||||
? ""
|
||||
: t("MoveToTrashFolderFromPersonal");
|
||||
} else if (pathname.startsWith("/rooms/shared")) {
|
||||
return !isFolder
|
||||
? t("MoveToTrashFile")
|
||||
: personal
|
||||
? ""
|
||||
: t("MoveToTrashFolder");
|
||||
}
|
||||
if (isRecycleBinFolder) {
|
||||
return isSingle
|
||||
? t(isFolder ? "DeleteFolder" : "DeleteFile")
|
||||
: t("DeleteItems");
|
||||
}
|
||||
|
||||
if (isRecycleBinFolder) {
|
||||
return t(isFolder ? "DeleteFolder" : "DeleteFile");
|
||||
}
|
||||
if (isPersonalRoom) {
|
||||
return isSingle
|
||||
? t(
|
||||
isFolder
|
||||
? "MoveToTrashFolderFromPersonal"
|
||||
: "MoveToTrashFileFromPersonal"
|
||||
)
|
||||
: t("MoveToTrashItemsFromPersonal");
|
||||
}
|
||||
|
||||
if (isRoom) {
|
||||
return isSingle
|
||||
? t(isFolder ? "MoveToTrashFolder" : "MoveToTrashFile")
|
||||
: t("MoveToTrashItems");
|
||||
}
|
||||
};
|
||||
|
||||
@ -228,7 +223,12 @@ export default inject(
|
||||
unsubscribeAction,
|
||||
deleteRoomsAction,
|
||||
} = filesActionsStore;
|
||||
const { isPrivacyFolder, isRecycleBinFolder } = treeFoldersStore;
|
||||
const {
|
||||
isPrivacyFolder,
|
||||
isRecycleBinFolder,
|
||||
isPersonalRoom,
|
||||
isRoom,
|
||||
} = treeFoldersStore;
|
||||
|
||||
const {
|
||||
deleteDialogVisible: visible,
|
||||
@ -240,8 +240,6 @@ export default inject(
|
||||
setIsRoomDelete,
|
||||
} = dialogsStore;
|
||||
|
||||
const { personal } = auth.settingsStore;
|
||||
|
||||
return {
|
||||
selection: removeMediaItem
|
||||
? [removeMediaItem]
|
||||
@ -259,13 +257,13 @@ export default inject(
|
||||
unsubscribe,
|
||||
|
||||
setRemoveMediaItem,
|
||||
|
||||
personal,
|
||||
setBufferSelection,
|
||||
|
||||
isRoomDelete,
|
||||
setIsRoomDelete,
|
||||
deleteRoomsAction,
|
||||
isPersonalRoom,
|
||||
isRoom,
|
||||
};
|
||||
}
|
||||
)(withRouter(observer(DeleteDialog)));
|
||||
|
@ -3,7 +3,8 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
import { loadLanguagePath } from "SRC_DIR/helpers/utils";
|
||||
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
|
@ -3,8 +3,8 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
import { loadLanguagePath } from "SRC_DIR/helpers/utils";
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
newInstance
|
||||
|
@ -3,8 +3,8 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
import { loadLanguagePath } from "SRC_DIR/helpers/utils";
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
newInstance
|
||||
|
@ -3,8 +3,8 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
import { loadLanguagePath } from "SRC_DIR/helpers/utils";
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
newInstance
|
||||
|
@ -3,8 +3,8 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
import { loadLanguagePath } from "SRC_DIR/helpers/utils";
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
newInstance
|
||||
|
@ -3,8 +3,8 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
import { loadLanguagePath } from "SRC_DIR/helpers/utils";
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
newInstance
|
||||
|
@ -3,8 +3,8 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
import { loadLanguagePath } from "SRC_DIR/helpers/utils";
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
newInstance
|
||||
|
3100
packages/client/src/helpers/autoGeneratedTranslations.js
Normal file
3100
packages/client/src/helpers/autoGeneratedTranslations.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,9 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
|
||||
import { loadLanguagePath } from "./utils";
|
||||
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
import authStore from "@docspace/common/store/AuthStore";
|
||||
import { toCommunityHostname } from "@docspace/common/utils";
|
||||
import { toCommunityHostname, getLanguage } from "@docspace/common/utils";
|
||||
import history from "@docspace/common/history";
|
||||
import { CategoryType } from "./constants";
|
||||
import { FolderType } from "@docspace/common/constants";
|
||||
import { translations } from "./autoGeneratedTranslations";
|
||||
|
||||
export const setDocumentTitle = (subTitle = null) => {
|
||||
const { isAuthenticated, settingsStore, product: currentModule } = authStore;
|
||||
@ -24,6 +25,31 @@ export const setDocumentTitle = (subTitle = null) => {
|
||||
document.title = title;
|
||||
};
|
||||
|
||||
export function loadLanguagePath(homepage, fixedNS = null) {
|
||||
return (lng, ns) => {
|
||||
const language = getLanguage(lng instanceof Array ? lng[0] : lng);
|
||||
|
||||
const lngCollection = translations.get(language);
|
||||
|
||||
const data = lngCollection?.get(`${fixedNS || ns}`);
|
||||
|
||||
if (!data) return `/locales/${language}/${fixedNS || ns}.json`;
|
||||
|
||||
let path = data?.split("/");
|
||||
const length = path?.length;
|
||||
|
||||
const isCommonPath = path[length - 1].indexOf("Common") > -1;
|
||||
|
||||
path = `/${path[length - 3]}/${path[length - 2]}/${path[length - 1]}`;
|
||||
|
||||
if (ns.length > 0 && ns[0] === "Common" && isCommonPath) {
|
||||
return `/static${path}`;
|
||||
}
|
||||
|
||||
return path;
|
||||
};
|
||||
}
|
||||
|
||||
export const checkIfModuleOld = (link) => {
|
||||
if (
|
||||
!link ||
|
||||
|
@ -3,7 +3,9 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
|
||||
import { loadLanguagePath } from "./helpers/utils";
|
||||
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
|
@ -3,8 +3,8 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
import { loadLanguagePath } from "SRC_DIR/helpers/utils";
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
newInstance
|
||||
|
@ -3,8 +3,8 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
import { loadLanguagePath } from "SRC_DIR/helpers/utils";
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
newInstance
|
||||
|
@ -3,8 +3,8 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
import { loadLanguagePath } from "SRC_DIR/helpers/utils";
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
newInstance
|
||||
|
@ -3,8 +3,8 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
import { loadLanguagePath } from "SRC_DIR/helpers/utils";
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
newInstance
|
||||
|
@ -3,8 +3,8 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
import { loadLanguagePath } from "SRC_DIR/helpers/utils";
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
newInstance
|
||||
|
@ -3,7 +3,7 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { loadLanguagePath } from "@docspace/common/utils";
|
||||
import { loadLanguagePath } from "SRC_DIR/helpers/utils";
|
||||
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
|
@ -3,8 +3,8 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
import { loadLanguagePath } from "SRC_DIR/helpers/utils";
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
newInstance
|
||||
|
@ -3,8 +3,8 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
import { loadLanguagePath } from "SRC_DIR/helpers/utils";
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
newInstance
|
||||
|
@ -100,9 +100,9 @@ const Customization = (props) => {
|
||||
{!isLoadedPage ? (
|
||||
<LoaderDescriptionCustomization />
|
||||
) : (
|
||||
<div className="category-description">{`${t(
|
||||
"Settings:CustomizationDescription"
|
||||
)}`}</div>
|
||||
<div className="category-description">
|
||||
{t("Settings:CustomizationDescription")}
|
||||
</div>
|
||||
)}
|
||||
<LanguageAndTimeZone isMobileView={isMobile} />
|
||||
<StyledSettingsSeparator />
|
||||
|
@ -17,6 +17,7 @@ export const MainContainer = styled.div`
|
||||
|
||||
.subtitle {
|
||||
margin-bottom: 20px;
|
||||
color: ${(props) => props.theme.client.settings.common.descriptionColor};
|
||||
}
|
||||
|
||||
.settings_tabs {
|
||||
|
@ -27,6 +27,10 @@ const MainContainer = styled.div`
|
||||
max-width: 700px;
|
||||
}
|
||||
|
||||
.login-history-description {
|
||||
color: ${(props) => props.theme.client.settings.common.descriptionColor};
|
||||
}
|
||||
|
||||
.save-cancel {
|
||||
padding: 0;
|
||||
position: static;
|
||||
@ -184,7 +188,7 @@ const HistoryMainContent = (props) => {
|
||||
<Badge backgroundColor="#EDC409" label="Paid" isPaidBadge={true} />
|
||||
)}
|
||||
<div className="main-wrapper">
|
||||
<Text fontSize="13px" color="#657077" className="settings_unavailable">
|
||||
<Text fontSize="13px" className="login-history-description">
|
||||
{subHeader}
|
||||
</Text>
|
||||
<Text className="latest-text settings_unavailable">{latestText} </Text>
|
||||
|
@ -3,8 +3,8 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
import { loadLanguagePath } from "SRC_DIR/helpers/utils";
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
newInstance
|
||||
|
@ -682,6 +682,8 @@ class FilesStore {
|
||||
console.log("[WS] subscribe to file's changes", file.id, file.title)
|
||||
);
|
||||
}
|
||||
|
||||
this.viewAs === "tile" && this.createThumbnails();
|
||||
};
|
||||
|
||||
setFolders = (folders) => {
|
||||
@ -1102,8 +1104,6 @@ class FilesStore {
|
||||
selectedFolder: { ...this.selectedFolderStore },
|
||||
};
|
||||
|
||||
this.viewAs === "tile" && this.createThumbnails();
|
||||
|
||||
if (this.createdItem) {
|
||||
const newItem = this.filesList.find(
|
||||
(item) => item.id === this.createdItem.id
|
||||
@ -1237,8 +1237,6 @@ class FilesStore {
|
||||
selectedFolder: { ...this.selectedFolderStore },
|
||||
};
|
||||
|
||||
this.viewAs === "tile" && this.createThumbnails();
|
||||
|
||||
if (this.createdItem) {
|
||||
const newItem = this.filesList.find(
|
||||
(item) => item.id === this.createdItem.id
|
||||
@ -2384,16 +2382,16 @@ class FilesStore {
|
||||
isArchive
|
||||
);
|
||||
|
||||
const defaultRoomIcon =
|
||||
isRoom &&
|
||||
getIcon(
|
||||
iconSize,
|
||||
fileExst,
|
||||
providerKey,
|
||||
contentLength,
|
||||
roomType,
|
||||
isArchive
|
||||
);
|
||||
const defaultRoomIcon = isRoom
|
||||
? getIcon(
|
||||
iconSize,
|
||||
fileExst,
|
||||
providerKey,
|
||||
contentLength,
|
||||
roomType,
|
||||
isArchive
|
||||
)
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
access,
|
||||
@ -2944,16 +2942,13 @@ class FilesStore {
|
||||
};
|
||||
|
||||
createThumbnails = () => {
|
||||
const filesList = [...this.files, this.folders];
|
||||
const fileIds = [];
|
||||
|
||||
filesList.map((file) => {
|
||||
const { thumbnailStatus } = file;
|
||||
|
||||
if (thumbnailStatus === thumbnailStatuses.WAITING) fileIds.push(file.id);
|
||||
const files = this.files?.filter((file) => {
|
||||
return file?.thumbnailStatus === thumbnailStatuses.WAITING;
|
||||
});
|
||||
|
||||
if (fileIds.length) return api.files.createThumbnails(fileIds);
|
||||
if (!files?.length) return;
|
||||
|
||||
return api.files.createThumbnails(files.map((f) => f.id));
|
||||
};
|
||||
|
||||
createThumbnail = async (fileId) => {
|
||||
|
@ -199,6 +199,14 @@ class TreeFoldersStore {
|
||||
);
|
||||
}
|
||||
|
||||
get isRoom() {
|
||||
return (
|
||||
this.roomsFolder &&
|
||||
this.roomsFolder.rootFolderType ===
|
||||
this.selectedFolderStore.rootFolderType
|
||||
);
|
||||
}
|
||||
|
||||
get isArchiveFolder() {
|
||||
return (
|
||||
this.archiveFolder &&
|
||||
|
@ -4,13 +4,18 @@ const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
const ModuleFederationPlugin = require("webpack").container
|
||||
.ModuleFederationPlugin;
|
||||
const DefinePlugin = require("webpack").DefinePlugin;
|
||||
const PrebuildWebpackPlugin = require("prebuild-webpack-plugin");
|
||||
const ExternalTemplateRemotesPlugin = require("external-remotes-plugin");
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
const combineUrl = require("@docspace/common/utils/combineUrl");
|
||||
const minifyJson = require("@docspace/common/utils/minifyJson");
|
||||
const beforeBuild = require("@docspace/common/utils/beforeBuild");
|
||||
const sharedDeps = require("@docspace/common/constants/sharedDependencies");
|
||||
const fs = require("fs");
|
||||
const { readdir } = require("fs").promises;
|
||||
|
||||
const path = require("path");
|
||||
|
||||
const pkg = require("./package.json");
|
||||
const deps = pkg.dependencies || {};
|
||||
const homepage = pkg.homepage; //combineUrl(window.DocSpaceConfig?.proxy?.url, pkg.homepage);
|
||||
@ -98,7 +103,7 @@ const config = {
|
||||
|
||||
folder += result.length === 0 ? "" : "/";
|
||||
|
||||
return `${folder}[name][ext]?hash=[contenthash]`; // `${folder}/[name].[contenthash][ext]`;
|
||||
return `static/${folder}[name][ext]?hash=[contenthash]`; // `${folder}/[name].[contenthash][ext]`;
|
||||
},
|
||||
},
|
||||
|
||||
@ -110,14 +115,50 @@ const config = {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|ico)$/i,
|
||||
test: /\.(png|jpe?g|gif|ico|woff2)$/i,
|
||||
type: "asset/resource",
|
||||
generator: {
|
||||
emit: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.svg$/i,
|
||||
type: "asset/resource",
|
||||
generator: {
|
||||
emit: false,
|
||||
},
|
||||
resourceQuery: /url/, // *.svg?url
|
||||
},
|
||||
{
|
||||
test: /\.json$/,
|
||||
resourceQuery: /url/,
|
||||
use: [
|
||||
{
|
||||
loader: "file-loader",
|
||||
options: {
|
||||
emitFile: false,
|
||||
name: (resourcePath) => {
|
||||
let result = resourcePath
|
||||
.split(`public${path.sep}`)[1]
|
||||
.split(path.sep);
|
||||
|
||||
result.pop();
|
||||
|
||||
let folder = result.join("/");
|
||||
|
||||
folder += result.length === 0 ? "" : "/";
|
||||
|
||||
return `${folder}[name].[ext]?hash=[contenthash]`; // `${folder}/[name].[contenthash][ext]`;
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.json$/,
|
||||
resourceQuery: { not: [/url/] }, // exclude if *.json?url,
|
||||
loader: "json-loader",
|
||||
},
|
||||
{
|
||||
test: /\.svg$/i,
|
||||
issuer: /\.[jt]sx?$/,
|
||||
@ -140,7 +181,6 @@ const config = {
|
||||
fullySpecified: false,
|
||||
},
|
||||
},
|
||||
{ test: /\.json$/, loader: "json-loader" },
|
||||
{
|
||||
test: /\.css$/i,
|
||||
use: ["style-loader", "css-loader"],
|
||||
@ -200,7 +240,17 @@ const config = {
|
||||
plugins: [
|
||||
new CleanWebpackPlugin(),
|
||||
new ExternalTemplateRemotesPlugin(),
|
||||
|
||||
new PrebuildWebpackPlugin({
|
||||
build: async (compiler, compilation, matchedFiles) => {
|
||||
await beforeBuild(
|
||||
[
|
||||
path.join(__dirname, "./public/locales"),
|
||||
path.join(__dirname, "../../public/locales"),
|
||||
],
|
||||
path.join(__dirname, "./src/helpers/autoGeneratedTranslations.js")
|
||||
);
|
||||
},
|
||||
}),
|
||||
new CopyPlugin({
|
||||
patterns: [
|
||||
// {
|
||||
|
@ -508,7 +508,7 @@ class MediaViewer extends React.Component {
|
||||
|
||||
const archiveRoom =
|
||||
archiveRoomsId === targetFile.rootFolderId ||
|
||||
(!targetFile.security.Rename && !targetFile.security.Delete);
|
||||
(!targetFile?.security?.Rename && !targetFile?.security?.Delete);
|
||||
const { title } = currentFile;
|
||||
|
||||
let isImage = false;
|
||||
|
@ -4,7 +4,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: local("Open Sans Light"), local("OpenSans-Light"),
|
||||
url("/static/fonts/DXI1ORHCpsQm3Vp6mXoaTa-j2U0lmluP9RWlSytm3ho.woff2")
|
||||
url("../../public/fonts/DXI1ORHCpsQm3Vp6mXoaTa-j2U0lmluP9RWlSytm3ho.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
|
||||
}
|
||||
@ -14,7 +14,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: local("Open Sans Light"), local("OpenSans-Light"),
|
||||
url("/static/fonts/DXI1ORHCpsQm3Vp6mXoaTZX5f-9o1vgP2EXwfjgl7AY.woff2")
|
||||
url("../../public/fonts/DXI1ORHCpsQm3Vp6mXoaTZX5f-9o1vgP2EXwfjgl7AY.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
@ -24,7 +24,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: local("Open Sans Light"), local("OpenSans-Light"),
|
||||
url("/static/fonts/DXI1ORHCpsQm3Vp6mXoaTRWV49_lSm1NYrwo-zkhivY.woff2")
|
||||
url("../../public/fonts/DXI1ORHCpsQm3Vp6mXoaTRWV49_lSm1NYrwo-zkhivY.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
@ -34,7 +34,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: local("Open Sans Light"), local("OpenSans-Light"),
|
||||
url("/static/fonts/DXI1ORHCpsQm3Vp6mXoaTaaRobkAwv3vxw3jMhVENGA.woff2")
|
||||
url("../../public/fonts/DXI1ORHCpsQm3Vp6mXoaTaaRobkAwv3vxw3jMhVENGA.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
@ -44,7 +44,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: local("Open Sans Light"), local("OpenSans-Light"),
|
||||
url("/static/fonts/DXI1ORHCpsQm3Vp6mXoaTf8zf_FOSsgRmwsS7Aa9k2w.woff2")
|
||||
url("../../public/fonts/DXI1ORHCpsQm3Vp6mXoaTf8zf_FOSsgRmwsS7Aa9k2w.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
|
||||
}
|
||||
@ -54,7 +54,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: local("Open Sans Light"), local("OpenSans-Light"),
|
||||
url("/static/fonts/DXI1ORHCpsQm3Vp6mXoaTT0LW-43aMEzIO6XUTLjad8.woff2")
|
||||
url("../../public/fonts/DXI1ORHCpsQm3Vp6mXoaTT0LW-43aMEzIO6XUTLjad8.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F,
|
||||
U+A720-A7FF;
|
||||
@ -65,7 +65,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: local("Open Sans Light"), local("OpenSans-Light"),
|
||||
url("/static/fonts/DXI1ORHCpsQm3Vp6mXoaTegdm0LZdjqr5-oayXSOefg.woff2")
|
||||
url("../../public/fonts/DXI1ORHCpsQm3Vp6mXoaTegdm0LZdjqr5-oayXSOefg.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC,
|
||||
U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
@ -76,7 +76,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local("Open Sans"), local("OpenSans"),
|
||||
url("/static/fonts/K88pR3goAWT7BTt32Z01mxJtnKITppOI_IvcXXDNrsc.woff2")
|
||||
url("../../public/fonts/K88pR3goAWT7BTt32Z01mxJtnKITppOI_IvcXXDNrsc.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
|
||||
}
|
||||
@ -86,7 +86,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local("Open Sans"), local("OpenSans"),
|
||||
url("/static/fonts/RjgO7rYTmqiVp7vzi-Q5URJtnKITppOI_IvcXXDNrsc.woff2")
|
||||
url("../../public/fonts/RjgO7rYTmqiVp7vzi-Q5URJtnKITppOI_IvcXXDNrsc.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
@ -96,7 +96,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local("Open Sans"), local("OpenSans"),
|
||||
url("/static/fonts/LWCjsQkB6EMdfHrEVqA1KRJtnKITppOI_IvcXXDNrsc.woff2")
|
||||
url("../../public/fonts/LWCjsQkB6EMdfHrEVqA1KRJtnKITppOI_IvcXXDNrsc.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
@ -106,7 +106,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local("Open Sans"), local("OpenSans"),
|
||||
url("/static/fonts/xozscpT2726on7jbcb_pAhJtnKITppOI_IvcXXDNrsc.woff2")
|
||||
url("../../public/fonts/xozscpT2726on7jbcb_pAhJtnKITppOI_IvcXXDNrsc.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
@ -116,7 +116,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local("Open Sans"), local("OpenSans"),
|
||||
url("/static/fonts/59ZRklaO5bWGqF5A9baEERJtnKITppOI_IvcXXDNrsc.woff2")
|
||||
url("../../public/fonts/59ZRklaO5bWGqF5A9baEERJtnKITppOI_IvcXXDNrsc.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
|
||||
}
|
||||
@ -126,7 +126,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local("Open Sans"), local("OpenSans"),
|
||||
url("/static/fonts/u-WUoqrET9fUeobQW7jkRRJtnKITppOI_IvcXXDNrsc.woff2")
|
||||
url("../../public/fonts/u-WUoqrET9fUeobQW7jkRRJtnKITppOI_IvcXXDNrsc.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F,
|
||||
U+A720-A7FF;
|
||||
@ -137,7 +137,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local("Open Sans"), local("OpenSans"),
|
||||
url("/static/fonts/cJZKeOuBrn4kERxqtaUH3VtXRa8TVwTICgirnJhmVJw.woff2")
|
||||
url("../../public/fonts/cJZKeOuBrn4kERxqtaUH3VtXRa8TVwTICgirnJhmVJw.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC,
|
||||
U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
@ -148,7 +148,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: local("Open Sans Semibold"), local("OpenSans-Semibold"),
|
||||
url("/static/fonts/MTP_ySUJH_bn48VBG8sNSq-j2U0lmluP9RWlSytm3ho.woff2")
|
||||
url("../../public/fonts/MTP_ySUJH_bn48VBG8sNSq-j2U0lmluP9RWlSytm3ho.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
|
||||
}
|
||||
@ -158,7 +158,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: local("Open Sans Semibold"), local("OpenSans-Semibold"),
|
||||
url("/static/fonts/MTP_ySUJH_bn48VBG8sNSpX5f-9o1vgP2EXwfjgl7AY.woff2")
|
||||
url("../../public/fonts/MTP_ySUJH_bn48VBG8sNSpX5f-9o1vgP2EXwfjgl7AY.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
@ -168,7 +168,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: local("Open Sans Semibold"), local("OpenSans-Semibold"),
|
||||
url("/static/fonts/MTP_ySUJH_bn48VBG8sNShWV49_lSm1NYrwo-zkhivY.woff2")
|
||||
url("../../public/fonts/MTP_ySUJH_bn48VBG8sNShWV49_lSm1NYrwo-zkhivY.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
@ -178,7 +178,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: local("Open Sans Semibold"), local("OpenSans-Semibold"),
|
||||
url("/static/fonts/MTP_ySUJH_bn48VBG8sNSqaRobkAwv3vxw3jMhVENGA.woff2")
|
||||
url("../../public/fonts/MTP_ySUJH_bn48VBG8sNSqaRobkAwv3vxw3jMhVENGA.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
@ -188,7 +188,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: local("Open Sans Semibold"), local("OpenSans-Semibold"),
|
||||
url("/static/fonts/MTP_ySUJH_bn48VBG8sNSv8zf_FOSsgRmwsS7Aa9k2w.woff2")
|
||||
url("../../public/fonts/MTP_ySUJH_bn48VBG8sNSv8zf_FOSsgRmwsS7Aa9k2w.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
|
||||
}
|
||||
@ -198,7 +198,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: local("Open Sans Semibold"), local("OpenSans-Semibold"),
|
||||
url("/static/fonts/MTP_ySUJH_bn48VBG8sNSj0LW-43aMEzIO6XUTLjad8.woff2")
|
||||
url("../../public/fonts/MTP_ySUJH_bn48VBG8sNSj0LW-43aMEzIO6XUTLjad8.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F,
|
||||
U+A720-A7FF;
|
||||
@ -209,7 +209,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: local("Open Sans Semibold"), local("OpenSans-Semibold"),
|
||||
url("/static/fonts/MTP_ySUJH_bn48VBG8sNSugdm0LZdjqr5-oayXSOefg.woff2")
|
||||
url("../../public/fonts/MTP_ySUJH_bn48VBG8sNSugdm0LZdjqr5-oayXSOefg.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC,
|
||||
U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
@ -220,7 +220,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local("Open Sans Bold"), local("OpenSans-Bold"),
|
||||
url("/static/fonts/k3k702ZOKiLJc3WVjuplzK-j2U0lmluP9RWlSytm3ho.woff2")
|
||||
url("../../public/fonts/k3k702ZOKiLJc3WVjuplzK-j2U0lmluP9RWlSytm3ho.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
|
||||
}
|
||||
@ -230,7 +230,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local("Open Sans Bold"), local("OpenSans-Bold"),
|
||||
url("/static/fonts/k3k702ZOKiLJc3WVjuplzJX5f-9o1vgP2EXwfjgl7AY.woff2")
|
||||
url("../../public/fonts/k3k702ZOKiLJc3WVjuplzJX5f-9o1vgP2EXwfjgl7AY.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
@ -240,7 +240,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local("Open Sans Bold"), local("OpenSans-Bold"),
|
||||
url("/static/fonts/k3k702ZOKiLJc3WVjuplzBWV49_lSm1NYrwo-zkhivY.woff2")
|
||||
url("../../public/fonts/k3k702ZOKiLJc3WVjuplzBWV49_lSm1NYrwo-zkhivY.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
@ -250,7 +250,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local("Open Sans Bold"), local("OpenSans-Bold"),
|
||||
url("/static/fonts/k3k702ZOKiLJc3WVjuplzKaRobkAwv3vxw3jMhVENGA.woff2")
|
||||
url("../../public/fonts/k3k702ZOKiLJc3WVjuplzKaRobkAwv3vxw3jMhVENGA.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
@ -260,7 +260,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local("Open Sans Bold"), local("OpenSans-Bold"),
|
||||
url("/static/fonts/k3k702ZOKiLJc3WVjuplzP8zf_FOSsgRmwsS7Aa9k2w.woff2")
|
||||
url("../../public/fonts/k3k702ZOKiLJc3WVjuplzP8zf_FOSsgRmwsS7Aa9k2w.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
|
||||
}
|
||||
@ -270,7 +270,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local("Open Sans Bold"), local("OpenSans-Bold"),
|
||||
url("/static/fonts/k3k702ZOKiLJc3WVjuplzD0LW-43aMEzIO6XUTLjad8.woff2")
|
||||
url("../../public/fonts/k3k702ZOKiLJc3WVjuplzD0LW-43aMEzIO6XUTLjad8.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F,
|
||||
U+A720-A7FF;
|
||||
@ -281,7 +281,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local("Open Sans Bold"), local("OpenSans-Bold"),
|
||||
url("/static/fonts/k3k702ZOKiLJc3WVjuplzOgdm0LZdjqr5-oayXSOefg.woff2")
|
||||
url("../../public/fonts/k3k702ZOKiLJc3WVjuplzOgdm0LZdjqr5-oayXSOefg.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC,
|
||||
U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
@ -292,7 +292,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
src: local("Open Sans Extrabold"), local("OpenSans-Extrabold"),
|
||||
url("/static/fonts/EInbV5DfGHOiMmvb1Xr-hq-j2U0lmluP9RWlSytm3ho.woff2")
|
||||
url("../../public/fonts/EInbV5DfGHOiMmvb1Xr-hq-j2U0lmluP9RWlSytm3ho.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
|
||||
}
|
||||
@ -302,7 +302,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
src: local("Open Sans Extrabold"), local("OpenSans-Extrabold"),
|
||||
url("/static/fonts/EInbV5DfGHOiMmvb1Xr-hpX5f-9o1vgP2EXwfjgl7AY.woff2")
|
||||
url("../../public/fonts/EInbV5DfGHOiMmvb1Xr-hpX5f-9o1vgP2EXwfjgl7AY.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
@ -312,7 +312,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
src: local("Open Sans Extrabold"), local("OpenSans-Extrabold"),
|
||||
url("/static/fonts/EInbV5DfGHOiMmvb1Xr-hhWV49_lSm1NYrwo-zkhivY.woff2")
|
||||
url("../../public/fonts/EInbV5DfGHOiMmvb1Xr-hhWV49_lSm1NYrwo-zkhivY.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
@ -322,7 +322,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
src: local("Open Sans Extrabold"), local("OpenSans-Extrabold"),
|
||||
url("/static/fonts/EInbV5DfGHOiMmvb1Xr-hqaRobkAwv3vxw3jMhVENGA.woff2")
|
||||
url("../../public/fonts/EInbV5DfGHOiMmvb1Xr-hqaRobkAwv3vxw3jMhVENGA.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
@ -332,7 +332,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
src: local("Open Sans Extrabold"), local("OpenSans-Extrabold"),
|
||||
url("/static/fonts/EInbV5DfGHOiMmvb1Xr-hv8zf_FOSsgRmwsS7Aa9k2w.woff2")
|
||||
url("../../public/fonts/EInbV5DfGHOiMmvb1Xr-hv8zf_FOSsgRmwsS7Aa9k2w.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
|
||||
}
|
||||
@ -342,7 +342,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
src: local("Open Sans Extrabold"), local("OpenSans-Extrabold"),
|
||||
url("/static/fonts/EInbV5DfGHOiMmvb1Xr-hj0LW-43aMEzIO6XUTLjad8.woff2")
|
||||
url("../../public/fonts/EInbV5DfGHOiMmvb1Xr-hj0LW-43aMEzIO6XUTLjad8.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F,
|
||||
U+A720-A7FF;
|
||||
@ -353,7 +353,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
src: local("Open Sans Extrabold"), local("OpenSans-Extrabold"),
|
||||
url("/static/fonts/EInbV5DfGHOiMmvb1Xr-hugdm0LZdjqr5-oayXSOefg.woff2")
|
||||
url("../../public/fonts/EInbV5DfGHOiMmvb1Xr-hugdm0LZdjqr5-oayXSOefg.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC,
|
||||
U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
@ -364,7 +364,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
src: local("Open Sans Light Italic"), local("OpenSansLight-Italic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxhgVThLs8Y7ETJzDCYFCSLE.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxhgVThLs8Y7ETJzDCYFCSLE.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
|
||||
}
|
||||
@ -374,7 +374,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
src: local("Open Sans Light Italic"), local("OpenSansLight-Italic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxpiMaisvaUVUsYyVzOmndek.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxpiMaisvaUVUsYyVzOmndek.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
@ -384,7 +384,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
src: local("Open Sans Light Italic"), local("OpenSansLight-Italic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxrBAWGjcah5Ky0jbCgIwDB8.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxrBAWGjcah5Ky0jbCgIwDB8.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
@ -394,7 +394,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
src: local("Open Sans Light Italic"), local("OpenSansLight-Italic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxv14vlcfyPYlAcQy2UfDRm4.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxv14vlcfyPYlAcQy2UfDRm4.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
@ -404,7 +404,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
src: local("Open Sans Light Italic"), local("OpenSansLight-Italic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxqfJul7RR1X4poJgi27uS4w.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxqfJul7RR1X4poJgi27uS4w.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
|
||||
}
|
||||
@ -414,7 +414,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
src: local("Open Sans Light Italic"), local("OpenSansLight-Italic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxqvyPXdneeGd26m9EmFSSWg.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxqvyPXdneeGd26m9EmFSSWg.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F,
|
||||
U+A720-A7FF;
|
||||
@ -425,7 +425,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
src: local("Open Sans Light Italic"), local("OpenSansLight-Italic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxko2lTMeWA_kmIyWrkNCwPc.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxko2lTMeWA_kmIyWrkNCwPc.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC,
|
||||
U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
@ -436,7 +436,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local("Open Sans Italic"), local("OpenSans-Italic"),
|
||||
url("/static/fonts/xjAJXh38I15wypJXxuGMBjTOQ_MqJVwkKsUn0wKzc2I.woff2")
|
||||
url("../../public/fonts/xjAJXh38I15wypJXxuGMBjTOQ_MqJVwkKsUn0wKzc2I.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
|
||||
}
|
||||
@ -446,7 +446,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local("Open Sans Italic"), local("OpenSans-Italic"),
|
||||
url("/static/fonts/xjAJXh38I15wypJXxuGMBjUj_cnvWIuuBMVgbX098Mw.woff2")
|
||||
url("../../public/fonts/xjAJXh38I15wypJXxuGMBjUj_cnvWIuuBMVgbX098Mw.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
@ -456,7 +456,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local("Open Sans Italic"), local("OpenSans-Italic"),
|
||||
url("/static/fonts/xjAJXh38I15wypJXxuGMBkbcKLIaa1LC45dFaAfauRA.woff2")
|
||||
url("../../public/fonts/xjAJXh38I15wypJXxuGMBkbcKLIaa1LC45dFaAfauRA.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
@ -466,7 +466,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local("Open Sans Italic"), local("OpenSans-Italic"),
|
||||
url("/static/fonts/xjAJXh38I15wypJXxuGMBmo_sUJ8uO4YLWRInS22T3Y.woff2")
|
||||
url("../../public/fonts/xjAJXh38I15wypJXxuGMBmo_sUJ8uO4YLWRInS22T3Y.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
@ -476,7 +476,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local("Open Sans Italic"), local("OpenSans-Italic"),
|
||||
url("/static/fonts/xjAJXh38I15wypJXxuGMBr6up8jxqWt8HVA3mDhkV_0.woff2")
|
||||
url("../../public/fonts/xjAJXh38I15wypJXxuGMBr6up8jxqWt8HVA3mDhkV_0.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
|
||||
}
|
||||
@ -486,7 +486,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local("Open Sans Italic"), local("OpenSans-Italic"),
|
||||
url("/static/fonts/xjAJXh38I15wypJXxuGMBiYE0-AqJ3nfInTTiDXDjU4.woff2")
|
||||
url("../../public/fonts/xjAJXh38I15wypJXxuGMBiYE0-AqJ3nfInTTiDXDjU4.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F,
|
||||
U+A720-A7FF;
|
||||
@ -497,7 +497,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local("Open Sans Italic"), local("OpenSans-Italic"),
|
||||
url("/static/fonts/xjAJXh38I15wypJXxuGMBo4P5ICox8Kq3LLUNMylGO4.woff2")
|
||||
url("../../public/fonts/xjAJXh38I15wypJXxuGMBo4P5ICox8Kq3LLUNMylGO4.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC,
|
||||
U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
@ -508,7 +508,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
src: local("Open Sans Semibold Italic"), local("OpenSans-SemiboldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxmgpAmOCqD37_tyH_8Ri5MM.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxmgpAmOCqD37_tyH_8Ri5MM.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
|
||||
}
|
||||
@ -518,7 +518,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
src: local("Open Sans Semibold Italic"), local("OpenSans-SemiboldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxsPNMTLbnS9uQzHQlYieHUU.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxsPNMTLbnS9uQzHQlYieHUU.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
@ -528,7 +528,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
src: local("Open Sans Semibold Italic"), local("OpenSans-SemiboldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxgyhumQnPMBCoGYhRaNxyyY.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxgyhumQnPMBCoGYhRaNxyyY.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
@ -538,7 +538,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
src: local("Open Sans Semibold Italic"), local("OpenSans-SemiboldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxhUVAXEdVvYDDqrz3aeR0Yc.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxhUVAXEdVvYDDqrz3aeR0Yc.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
@ -548,7 +548,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
src: local("Open Sans Semibold Italic"), local("OpenSans-SemiboldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxlf4y_3s5bcYyyLIFUSWYUU.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxlf4y_3s5bcYyyLIFUSWYUU.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
|
||||
}
|
||||
@ -558,7 +558,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
src: local("Open Sans Semibold Italic"), local("OpenSans-SemiboldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxnywqdtBbUHn3VPgzuFrCy8.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxnywqdtBbUHn3VPgzuFrCy8.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F,
|
||||
U+A720-A7FF;
|
||||
@ -569,7 +569,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
src: local("Open Sans Semibold Italic"), local("OpenSans-SemiboldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxl2umOyRU7PgRiv8DXcgJjk.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxl2umOyRU7PgRiv8DXcgJjk.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC,
|
||||
U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
@ -580,7 +580,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: local("Open Sans Bold Italic"), local("OpenSans-BoldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxp6iIh_FvlUHQwED9Yt5Kbw.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxp6iIh_FvlUHQwED9Yt5Kbw.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
|
||||
}
|
||||
@ -590,7 +590,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: local("Open Sans Bold Italic"), local("OpenSans-BoldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxi_vZmeiCMnoWNN9rHBYaTc.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxi_vZmeiCMnoWNN9rHBYaTc.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
@ -600,7 +600,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: local("Open Sans Bold Italic"), local("OpenSans-BoldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxiFaMxiho_5XQnyRZzQsrZs.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxiFaMxiho_5XQnyRZzQsrZs.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
@ -610,7 +610,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: local("Open Sans Bold Italic"), local("OpenSans-BoldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxgalQocB-__pDVGhF3uS2Ks.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxgalQocB-__pDVGhF3uS2Ks.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
@ -620,7 +620,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: local("Open Sans Bold Italic"), local("OpenSans-BoldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxmhQUTDJGru-0vvUpABgH8I.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxmhQUTDJGru-0vvUpABgH8I.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
|
||||
}
|
||||
@ -630,7 +630,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: local("Open Sans Bold Italic"), local("OpenSans-BoldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxujkDdvhIIFj_YMdgqpnSB0.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxujkDdvhIIFj_YMdgqpnSB0.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F,
|
||||
U+A720-A7FF;
|
||||
@ -641,7 +641,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: local("Open Sans Bold Italic"), local("OpenSans-BoldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxolIZu-HDpmDIZMigmsroc4.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxolIZu-HDpmDIZMigmsroc4.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC,
|
||||
U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
@ -652,7 +652,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 800;
|
||||
src: local("Open Sans Extrabold Italic"), local("OpenSans-ExtraboldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxiU8QAtQT9M0M1_mbVWrUPc.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxiU8QAtQT9M0M1_mbVWrUPc.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
|
||||
}
|
||||
@ -662,7 +662,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 800;
|
||||
src: local("Open Sans Extrabold Italic"), local("OpenSans-ExtraboldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxkNaUOL0oYRolx8sebiIY9k.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxkNaUOL0oYRolx8sebiIY9k.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
@ -672,7 +672,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 800;
|
||||
src: local("Open Sans Extrabold Italic"), local("OpenSans-ExtraboldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxooGEx1DzoxsbCRd2IM2afI.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxooGEx1DzoxsbCRd2IM2afI.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
@ -682,7 +682,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 800;
|
||||
src: local("Open Sans Extrabold Italic"), local("OpenSans-ExtraboldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxnPzCMEhbIaaYiFY6KPniws.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxnPzCMEhbIaaYiFY6KPniws.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
@ -692,7 +692,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 800;
|
||||
src: local("Open Sans Extrabold Italic"), local("OpenSans-ExtraboldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxmqi69zMYkLa7XwlUIemKB4.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxmqi69zMYkLa7XwlUIemKB4.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
|
||||
}
|
||||
@ -702,7 +702,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 800;
|
||||
src: local("Open Sans Extrabold Italic"), local("OpenSans-ExtraboldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxowYyzpnB4tyYboSwKGmD2g.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxowYyzpnB4tyYboSwKGmD2g.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F,
|
||||
U+A720-A7FF;
|
||||
@ -713,7 +713,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 800;
|
||||
src: local("Open Sans Extrabold Italic"), local("OpenSans-ExtraboldItalic"),
|
||||
url("/static/fonts/PRmiXeptR36kaC0GEAetxnibbpXgLHK_uTT48UMyjSM.woff2")
|
||||
url("../../public/fonts/PRmiXeptR36kaC0GEAetxnibbpXgLHK_uTT48UMyjSM.woff2")
|
||||
format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC,
|
||||
U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
|
@ -7,7 +7,7 @@ import i18n from "i18next";
|
||||
import { useTranslation, initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import { LANGUAGE } from "../constants";
|
||||
import { loadLanguagePath, getCookie } from "../utils";
|
||||
import { getCookie } from "../utils";
|
||||
|
||||
i18n
|
||||
.use(Backend)
|
||||
|
125
packages/common/utils/beforeBuild.js
Normal file
125
packages/common/utils/beforeBuild.js
Normal file
@ -0,0 +1,125 @@
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const { readdir } = require("fs").promises;
|
||||
|
||||
const appSettings = require("../../../config/appsettings.json");
|
||||
|
||||
const beforeBuild = async (pathsToLocales, pathToFile) => {
|
||||
async function* getFiles(dir) {
|
||||
const dirents = await readdir(dir, { withFileTypes: true });
|
||||
for (const dirent of dirents) {
|
||||
const res = path.resolve(dir, dirent.name);
|
||||
|
||||
if (dirent.isDirectory()) {
|
||||
yield* getFiles(res);
|
||||
} else {
|
||||
yield { path: res, fileName: dirent.name };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getLocalesFiles = async () => {
|
||||
const files = [];
|
||||
|
||||
for await (const p of pathsToLocales) {
|
||||
for await (const f of getFiles(p)) {
|
||||
if (f) files.push(f);
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
};
|
||||
|
||||
const localesFiles = await getLocalesFiles();
|
||||
|
||||
const cultures = appSettings.web.cultures;
|
||||
|
||||
const collectionByLng = new Map();
|
||||
const truthLng = new Map();
|
||||
|
||||
let importString = "\n";
|
||||
|
||||
localesFiles.forEach((file) => {
|
||||
const splitPath = file.path.split(path.sep);
|
||||
|
||||
const length = splitPath.length;
|
||||
|
||||
const url = [
|
||||
splitPath[length - 3],
|
||||
splitPath[length - 2],
|
||||
splitPath[length - 1],
|
||||
].join("/");
|
||||
|
||||
const fileName = splitPath[length - 1].split(".")[0];
|
||||
|
||||
let lng = splitPath[length - 2];
|
||||
|
||||
let language = lng == "en-US" || lng == "en-GB" ? "en" : lng;
|
||||
|
||||
if (cultures.indexOf(language) === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const splitted = lng.split("-");
|
||||
|
||||
if (splitted.length == 2 && splitted[0] == splitted[1].toLowerCase()) {
|
||||
language = splitted[0];
|
||||
}
|
||||
|
||||
truthLng.set(language, language.replace("-", ""));
|
||||
|
||||
language = language.replace("-", "");
|
||||
|
||||
const items = collectionByLng.get(language);
|
||||
|
||||
if (items && items.length > 0) {
|
||||
items.push(fileName);
|
||||
collectionByLng.set(language, items);
|
||||
} else {
|
||||
collectionByLng.set(language, [fileName]);
|
||||
}
|
||||
|
||||
const alias =
|
||||
fileName.indexOf("Common") === -1 ? "ASSETS_DIR" : "PUBLIC_DIR";
|
||||
|
||||
importString =
|
||||
importString +
|
||||
`import ${fileName}${language}Url from "${alias}/${url}?url";\n`;
|
||||
});
|
||||
|
||||
let content =
|
||||
`//THIS FILE IS AUTO GENERATED\n//DO NOT EDIT AND DELETE IT\n` +
|
||||
importString;
|
||||
|
||||
let generalCollection = `\n export const translations = new Map([`;
|
||||
|
||||
collectionByLng.forEach((collection, key) => {
|
||||
let collectionString = `\n const ${key} = new Map([`;
|
||||
|
||||
collection.forEach((c, index) => {
|
||||
collectionString += `\n["${c}", ${c}${key}Url]`;
|
||||
|
||||
if (index !== collection.length - 1) collectionString += `,`;
|
||||
});
|
||||
|
||||
collectionString += `\n]);`;
|
||||
|
||||
content += collectionString;
|
||||
});
|
||||
|
||||
truthLng.forEach((col, key) => {
|
||||
generalCollection += `\n["${key}", ${col}],`;
|
||||
});
|
||||
|
||||
generalCollection += `\n]);`;
|
||||
|
||||
content += generalCollection;
|
||||
|
||||
fs.writeFile(pathToFile, content, "utf8", function (err) {
|
||||
if (err) throw new Error(Error);
|
||||
|
||||
console.log("The auto generated translations file has been created!");
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = beforeBuild;
|
@ -22,6 +22,7 @@ import TopLoaderService from "@docspace/components/top-loading-indicator";
|
||||
import { Encoder } from "./encoder";
|
||||
import FilesFilter from "../api/files/filter";
|
||||
import combineUrlFunc from "./combineUrl";
|
||||
// import { translations } from "./i18next-http-backend/lib/translations";
|
||||
export const toUrlParams = (obj, skipNull) => {
|
||||
let str = "";
|
||||
for (var key in obj) {
|
||||
@ -291,17 +292,6 @@ export function getLanguage(lng) {
|
||||
return lng;
|
||||
}
|
||||
|
||||
export function loadLanguagePath(homepage, fixedNS = null) {
|
||||
return (lng, ns) => {
|
||||
const language = getLanguage(lng instanceof Array ? lng[0] : lng);
|
||||
|
||||
if (ns.length > 0 && ns[0] === "Common") {
|
||||
return `/static/locales/${language}/Common.json`;
|
||||
}
|
||||
return `${homepage}/locales/${language}/${fixedNS || ns}.json`;
|
||||
};
|
||||
}
|
||||
|
||||
export function loadScript(url, id, onLoad, onError) {
|
||||
try {
|
||||
const script = document.createElement("script");
|
||||
|
@ -43,6 +43,7 @@
|
||||
"json-loader": "^0.5.7",
|
||||
"nodemon": "^2.0.7",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prebuild-webpack-plugin": "^1.1.1",
|
||||
"sass": "^1.53.0",
|
||||
"sass-loader": "^13.0.2",
|
||||
"shx": "^0.3.4",
|
||||
|
188
packages/editor/src/autoGeneratedTranslations.js
Normal file
188
packages/editor/src/autoGeneratedTranslations.js
Normal file
@ -0,0 +1,188 @@
|
||||
//THIS FILE IS AUTO GENERATED
|
||||
//DO NOT EDIT AND DELETE IT
|
||||
|
||||
import EditorazUrl from "ASSETS_DIR/locales/az/Editor.json?url";
|
||||
import EditorbgUrl from "ASSETS_DIR/locales/bg/Editor.json?url";
|
||||
import EditorcsUrl from "ASSETS_DIR/locales/cs/Editor.json?url";
|
||||
import EditordeUrl from "ASSETS_DIR/locales/de/Editor.json?url";
|
||||
import EditorelGRUrl from "ASSETS_DIR/locales/el-GR/Editor.json?url";
|
||||
import EditorenUrl from "ASSETS_DIR/locales/en/Editor.json?url";
|
||||
import EditoresUrl from "ASSETS_DIR/locales/es/Editor.json?url";
|
||||
import EditorfiUrl from "ASSETS_DIR/locales/fi/Editor.json?url";
|
||||
import EditorfrUrl from "ASSETS_DIR/locales/fr/Editor.json?url";
|
||||
import EditoritUrl from "ASSETS_DIR/locales/it/Editor.json?url";
|
||||
import EditorjaJPUrl from "ASSETS_DIR/locales/ja-JP/Editor.json?url";
|
||||
import EditorkoKRUrl from "ASSETS_DIR/locales/ko-KR/Editor.json?url";
|
||||
import EditorloLAUrl from "ASSETS_DIR/locales/lo-LA/Editor.json?url";
|
||||
import EditorlvUrl from "ASSETS_DIR/locales/lv/Editor.json?url";
|
||||
import EditornlUrl from "ASSETS_DIR/locales/nl/Editor.json?url";
|
||||
import EditorplUrl from "ASSETS_DIR/locales/pl/Editor.json?url";
|
||||
import EditorptUrl from "ASSETS_DIR/locales/pt/Editor.json?url";
|
||||
import EditorptBRUrl from "ASSETS_DIR/locales/pt-BR/Editor.json?url";
|
||||
import EditorroUrl from "ASSETS_DIR/locales/ro/Editor.json?url";
|
||||
import EditorruUrl from "ASSETS_DIR/locales/ru/Editor.json?url";
|
||||
import EditorskUrl from "ASSETS_DIR/locales/sk/Editor.json?url";
|
||||
import EditorslUrl from "ASSETS_DIR/locales/sl/Editor.json?url";
|
||||
import EditortrUrl from "ASSETS_DIR/locales/tr/Editor.json?url";
|
||||
import EditorukUAUrl from "ASSETS_DIR/locales/uk-UA/Editor.json?url";
|
||||
import EditorviUrl from "ASSETS_DIR/locales/vi/Editor.json?url";
|
||||
import EditorzhCNUrl from "ASSETS_DIR/locales/zh-CN/Editor.json?url";
|
||||
import CommonazUrl from "PUBLIC_DIR/locales/az/Common.json?url";
|
||||
import CommonbgUrl from "PUBLIC_DIR/locales/bg/Common.json?url";
|
||||
import CommoncsUrl from "PUBLIC_DIR/locales/cs/Common.json?url";
|
||||
import CommondeUrl from "PUBLIC_DIR/locales/de/Common.json?url";
|
||||
import CommonelGRUrl from "PUBLIC_DIR/locales/el-GR/Common.json?url";
|
||||
import CommonenUrl from "PUBLIC_DIR/locales/en/Common.json?url";
|
||||
import CommonesUrl from "PUBLIC_DIR/locales/es/Common.json?url";
|
||||
import CommonfiUrl from "PUBLIC_DIR/locales/fi/Common.json?url";
|
||||
import CommonfrUrl from "PUBLIC_DIR/locales/fr/Common.json?url";
|
||||
import CommonitUrl from "PUBLIC_DIR/locales/it/Common.json?url";
|
||||
import CommonjaJPUrl from "PUBLIC_DIR/locales/ja-JP/Common.json?url";
|
||||
import CommonkoKRUrl from "PUBLIC_DIR/locales/ko-KR/Common.json?url";
|
||||
import CommonloLAUrl from "PUBLIC_DIR/locales/lo-LA/Common.json?url";
|
||||
import CommonlvUrl from "PUBLIC_DIR/locales/lv/Common.json?url";
|
||||
import CommonnlUrl from "PUBLIC_DIR/locales/nl/Common.json?url";
|
||||
import CommonplUrl from "PUBLIC_DIR/locales/pl/Common.json?url";
|
||||
import CommonptUrl from "PUBLIC_DIR/locales/pt/Common.json?url";
|
||||
import CommonptBRUrl from "PUBLIC_DIR/locales/pt-BR/Common.json?url";
|
||||
import CommonroUrl from "PUBLIC_DIR/locales/ro/Common.json?url";
|
||||
import CommonruUrl from "PUBLIC_DIR/locales/ru/Common.json?url";
|
||||
import CommonskUrl from "PUBLIC_DIR/locales/sk/Common.json?url";
|
||||
import CommonslUrl from "PUBLIC_DIR/locales/sl/Common.json?url";
|
||||
import CommontrUrl from "PUBLIC_DIR/locales/tr/Common.json?url";
|
||||
import CommonukUAUrl from "PUBLIC_DIR/locales/uk-UA/Common.json?url";
|
||||
import CommonviUrl from "PUBLIC_DIR/locales/vi/Common.json?url";
|
||||
import CommonzhCNUrl from "PUBLIC_DIR/locales/zh-CN/Common.json?url";
|
||||
|
||||
const az = new Map([
|
||||
["Editor", EditorazUrl],
|
||||
["Common", CommonazUrl]
|
||||
]);
|
||||
const bg = new Map([
|
||||
["Editor", EditorbgUrl],
|
||||
["Common", CommonbgUrl]
|
||||
]);
|
||||
const cs = new Map([
|
||||
["Editor", EditorcsUrl],
|
||||
["Common", CommoncsUrl]
|
||||
]);
|
||||
const de = new Map([
|
||||
["Editor", EditordeUrl],
|
||||
["Common", CommondeUrl]
|
||||
]);
|
||||
const elGR = new Map([
|
||||
["Editor", EditorelGRUrl],
|
||||
["Common", CommonelGRUrl]
|
||||
]);
|
||||
const en = new Map([
|
||||
["Editor", EditorenUrl],
|
||||
["Common", CommonenUrl]
|
||||
]);
|
||||
const es = new Map([
|
||||
["Editor", EditoresUrl],
|
||||
["Common", CommonesUrl]
|
||||
]);
|
||||
const fi = new Map([
|
||||
["Editor", EditorfiUrl],
|
||||
["Common", CommonfiUrl]
|
||||
]);
|
||||
const fr = new Map([
|
||||
["Editor", EditorfrUrl],
|
||||
["Common", CommonfrUrl]
|
||||
]);
|
||||
const it = new Map([
|
||||
["Editor", EditoritUrl],
|
||||
["Common", CommonitUrl]
|
||||
]);
|
||||
const jaJP = new Map([
|
||||
["Editor", EditorjaJPUrl],
|
||||
["Common", CommonjaJPUrl]
|
||||
]);
|
||||
const koKR = new Map([
|
||||
["Editor", EditorkoKRUrl],
|
||||
["Common", CommonkoKRUrl]
|
||||
]);
|
||||
const loLA = new Map([
|
||||
["Editor", EditorloLAUrl],
|
||||
["Common", CommonloLAUrl]
|
||||
]);
|
||||
const lv = new Map([
|
||||
["Editor", EditorlvUrl],
|
||||
["Common", CommonlvUrl]
|
||||
]);
|
||||
const nl = new Map([
|
||||
["Editor", EditornlUrl],
|
||||
["Common", CommonnlUrl]
|
||||
]);
|
||||
const pl = new Map([
|
||||
["Editor", EditorplUrl],
|
||||
["Common", CommonplUrl]
|
||||
]);
|
||||
const pt = new Map([
|
||||
["Editor", EditorptUrl],
|
||||
["Common", CommonptUrl]
|
||||
]);
|
||||
const ptBR = new Map([
|
||||
["Editor", EditorptBRUrl],
|
||||
["Common", CommonptBRUrl]
|
||||
]);
|
||||
const ro = new Map([
|
||||
["Editor", EditorroUrl],
|
||||
["Common", CommonroUrl]
|
||||
]);
|
||||
const ru = new Map([
|
||||
["Editor", EditorruUrl],
|
||||
["Common", CommonruUrl]
|
||||
]);
|
||||
const sk = new Map([
|
||||
["Editor", EditorskUrl],
|
||||
["Common", CommonskUrl]
|
||||
]);
|
||||
const sl = new Map([
|
||||
["Editor", EditorslUrl],
|
||||
["Common", CommonslUrl]
|
||||
]);
|
||||
const tr = new Map([
|
||||
["Editor", EditortrUrl],
|
||||
["Common", CommontrUrl]
|
||||
]);
|
||||
const ukUA = new Map([
|
||||
["Editor", EditorukUAUrl],
|
||||
["Common", CommonukUAUrl]
|
||||
]);
|
||||
const vi = new Map([
|
||||
["Editor", EditorviUrl],
|
||||
["Common", CommonviUrl]
|
||||
]);
|
||||
const zhCN = new Map([
|
||||
["Editor", EditorzhCNUrl],
|
||||
["Common", CommonzhCNUrl]
|
||||
]);
|
||||
export const translations = new Map([
|
||||
["az", az],
|
||||
["bg", bg],
|
||||
["cs", cs],
|
||||
["de", de],
|
||||
["el-GR", elGR],
|
||||
["en", en],
|
||||
["es", es],
|
||||
["fi", fi],
|
||||
["fr", fr],
|
||||
["it", it],
|
||||
["ja-JP", jaJP],
|
||||
["ko-KR", koKR],
|
||||
["lo-LA", loLA],
|
||||
["lv", lv],
|
||||
["nl", nl],
|
||||
["pl", pl],
|
||||
["pt", pt],
|
||||
["pt-BR", ptBR],
|
||||
["ro", ro],
|
||||
["ru", ru],
|
||||
["sk", sk],
|
||||
["sl", sl],
|
||||
["tr", tr],
|
||||
["uk-UA", ukUA],
|
||||
["vi", vi],
|
||||
["zh-CN", zhCN],
|
||||
]);
|
4
packages/editor/src/client/bootstrap.js
vendored
4
packages/editor/src/client/bootstrap.js
vendored
@ -1,6 +1,6 @@
|
||||
import React from "react";
|
||||
import { hydrate } from "react-dom";
|
||||
import { registerSW } from "@docspace/common/sw/helper";
|
||||
// import { registerSW } from "@docspace/common/sw/helper";
|
||||
import App from "./App.js";
|
||||
import pkg from "../../package.json";
|
||||
import { initI18n } from "./helpers/utils.js";
|
||||
@ -53,4 +53,4 @@ if (IS_DEVELOPMENT) {
|
||||
};
|
||||
}
|
||||
|
||||
registerSW();
|
||||
// registerSW();
|
||||
|
@ -1,26 +1,74 @@
|
||||
import pkg from "../../../package.json";
|
||||
import { translations } from "SRC_DIR/autoGeneratedTranslations";
|
||||
|
||||
export function getLanguage(lng) {
|
||||
try {
|
||||
let language = lng == "en-US" || lng == "en-GB" ? "en" : lng;
|
||||
|
||||
const splitted = lng.split("-");
|
||||
|
||||
if (splitted.length == 2 && splitted[0] == splitted[1].toLowerCase()) {
|
||||
language = splitted[0];
|
||||
}
|
||||
|
||||
return language;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
return lng;
|
||||
}
|
||||
|
||||
export function loadLanguagePath(homepage, fixedNS = null) {
|
||||
return (lng, ns) => {
|
||||
const language = getLanguage(lng instanceof Array ? lng[0] : lng);
|
||||
|
||||
const lngCollection = translations.get(language);
|
||||
|
||||
const path = lngCollection?.get(`${fixedNS || ns}`);
|
||||
|
||||
if (!path) return `/doceditor/locales/${language}/${fixedNS || ns}.json`;
|
||||
|
||||
const isCommonPath = path?.indexOf("Common") > -1;
|
||||
|
||||
if (ns.length > 0 && ns[0] === "Common" && isCommonPath) {
|
||||
return path.replace("/doceditor/", "/static/");
|
||||
}
|
||||
|
||||
return path;
|
||||
};
|
||||
}
|
||||
|
||||
export const initI18n = (initialI18nStoreASC) => {
|
||||
if (!initialI18nStoreASC || window.i18n) return;
|
||||
|
||||
const { homepage } = pkg;
|
||||
|
||||
window.i18n = {};
|
||||
window.i18n.inLoad = [];
|
||||
window.i18n.loaded = {};
|
||||
|
||||
for (let lng in initialI18nStoreASC) {
|
||||
const collection = translations.get(lng);
|
||||
|
||||
for (let ns in initialI18nStoreASC[lng]) {
|
||||
if (ns === "Common") {
|
||||
window.i18n.loaded[`/static/locales/${lng}/${ns}.json`] = {
|
||||
const path = collection?.get(ns);
|
||||
|
||||
if (!path) {
|
||||
window.i18n.loaded[`/doceditor/locales/${lng}/${ns}.json`] = {
|
||||
namespaces: ns,
|
||||
data: initialI18nStoreASC[lng][ns],
|
||||
};
|
||||
} else {
|
||||
window.i18n.loaded[`${homepage}/locales/${lng}/${ns}.json`] = {
|
||||
namespaces: ns,
|
||||
data: initialI18nStoreASC[lng][ns],
|
||||
};
|
||||
if (ns === "Common") {
|
||||
window.i18n.loaded[`${path?.replace("/doceditor/", "/static/")}`] = {
|
||||
namespaces: ns,
|
||||
data: initialI18nStoreASC[lng][ns],
|
||||
};
|
||||
} else {
|
||||
window.i18n.loaded[`${path}`] = {
|
||||
namespaces: ns,
|
||||
data: initialI18nStoreASC[lng][ns],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,8 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import config from "../../package.json";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
import { loadLanguagePath } from "./helpers/utils";
|
||||
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
|
@ -13,6 +13,7 @@ import winston from "./lib/logger.js";
|
||||
import { getAssets, initDocEditor } from "./lib/helpers";
|
||||
import renderApp from "./lib/helpers/render-app";
|
||||
import dns from "dns";
|
||||
import { translations } from "SRC_DIR/autoGeneratedTranslations";
|
||||
|
||||
dns.setDefaultResultOrder("ipv4first");
|
||||
|
||||
@ -32,15 +33,9 @@ winston.stream = {
|
||||
};
|
||||
|
||||
const loadPath = (lng, ns) => {
|
||||
let resourcePath = path.resolve(
|
||||
path.join(__dirname, "client", `locales/${lng}/${ns}.json`)
|
||||
);
|
||||
if (ns === "Common")
|
||||
resourcePath = path.resolve(
|
||||
path.join(__dirname, `../../../public/locales/${lng}/${ns}.json`)
|
||||
);
|
||||
const path = translations?.get(lng)?.get(ns);
|
||||
|
||||
return resourcePath;
|
||||
return path;
|
||||
};
|
||||
|
||||
const app = express();
|
||||
|
@ -20,10 +20,7 @@ import { getLogoFromPath } from "@docspace/common/utils";
|
||||
export const getFavicon = (logoUrls) => {
|
||||
if (!logoUrls) return null;
|
||||
|
||||
return getLogoFromPath(logoUrls[2]?.path?.light).replace(
|
||||
"client/",
|
||||
"/doceditor/"
|
||||
);
|
||||
return getLogoFromPath(logoUrls[2]?.path?.light);
|
||||
};
|
||||
|
||||
export const initDocEditor = async (req) => {
|
||||
@ -114,23 +111,16 @@ export const initDocEditor = async (req) => {
|
||||
|
||||
config.editorConfig.customization.logo.image =
|
||||
config.editorConfig.customization.logo.url +
|
||||
getLogoFromPath(config.editorConfig.customization.logo.image)?.replace(
|
||||
"client/",
|
||||
"doceditor/"
|
||||
);
|
||||
getLogoFromPath(config.editorConfig.customization.logo.image);
|
||||
|
||||
config.editorConfig.customization.logo.imageDark =
|
||||
config.editorConfig.customization.logo.url +
|
||||
getLogoFromPath(
|
||||
config.editorConfig.customization.logo.imageDark
|
||||
)?.replace("client/", "doceditor/");
|
||||
getLogoFromPath(config.editorConfig.customization.logo.imageDark);
|
||||
|
||||
if (config.editorConfig.customization.customer) {
|
||||
config.editorConfig.customization.customer.logo =
|
||||
config.editorConfig.customization.logo.url +
|
||||
getLogoFromPath(
|
||||
config.editorConfig.customization.customer.logo
|
||||
)?.replace("client/", "doceditor/");
|
||||
getLogoFromPath(config.editorConfig.customization.customer.logo);
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -12,10 +12,7 @@ export default function template(
|
||||
const { title } = pkg;
|
||||
const { error } = initialEditorState;
|
||||
const editorUrl = initialEditorState?.config?.editorUrl;
|
||||
const faviconHref = getFavicon(initialEditorState?.logoUrls)?.replace(
|
||||
"client/",
|
||||
"doceditor/"
|
||||
);
|
||||
const faviconHref = getFavicon(initialEditorState?.logoUrls);
|
||||
|
||||
let clientScripts =
|
||||
assets && assets.hasOwnProperty("client.js")
|
||||
|
@ -1,5 +1,7 @@
|
||||
const path = require("path");
|
||||
const FilterWarningsPlugin = require("webpack-filter-warnings-plugin");
|
||||
const PrebuildWebpackPlugin = require("prebuild-webpack-plugin");
|
||||
const beforeBuild = require("@docspace/common/utils/beforeBuild");
|
||||
|
||||
const scriptExtensions = /\.(tsx|ts|js|jsx|mjs)$/;
|
||||
const imageExtensions = /\.(bmp|gif|jpg|jpeg|png|ico)$/;
|
||||
@ -13,6 +15,7 @@ module.exports = {
|
||||
},
|
||||
alias: {
|
||||
PUBLIC_DIR: path.resolve(__dirname, "../../../public"),
|
||||
ASSETS_DIR: path.resolve(__dirname, "../public"),
|
||||
SRC_DIR: path.resolve(__dirname, "../src"),
|
||||
PACKAGE_FILE: path.resolve(__dirname, "../package.json"),
|
||||
},
|
||||
@ -42,7 +45,10 @@ module.exports = {
|
||||
},
|
||||
{
|
||||
test: fontsExtension,
|
||||
type: "asset",
|
||||
generator: {
|
||||
emit: false,
|
||||
},
|
||||
type: "asset/resource",
|
||||
},
|
||||
{
|
||||
test: /\.svg/,
|
||||
@ -52,13 +58,51 @@ module.exports = {
|
||||
},
|
||||
{
|
||||
test: imageExtensions,
|
||||
generator: {
|
||||
emit: false,
|
||||
},
|
||||
type: "asset/resource",
|
||||
},
|
||||
{
|
||||
test: /\.svg$/i,
|
||||
generator: {
|
||||
emit: false,
|
||||
},
|
||||
type: "asset/resource",
|
||||
resourceQuery: /url/, // *.svg?url
|
||||
},
|
||||
{
|
||||
test: /\.json$/,
|
||||
resourceQuery: /url/,
|
||||
type: "javascript/auto",
|
||||
use: [
|
||||
{
|
||||
loader: "file-loader",
|
||||
options: {
|
||||
emitFile: false,
|
||||
name: (resourcePath) => {
|
||||
let result = resourcePath
|
||||
.split(`public${path.sep}`)[1]
|
||||
.split(path.sep);
|
||||
|
||||
result.pop();
|
||||
|
||||
let folder = result.join("/");
|
||||
|
||||
folder += result.length === 0 ? "" : "/";
|
||||
|
||||
return `${folder}[name].[ext]?hash=[contenthash]`; // `${folder}/[name].[contenthash][ext]`;
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.json$/,
|
||||
resourceQuery: { not: [/url/] }, // exclude if *.json?url,
|
||||
loader: "json-loader",
|
||||
type: "javascript/auto",
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
|
@ -9,6 +9,8 @@ const ExternalTemplateRemotesPlugin = require("external-remotes-plugin");
|
||||
const CopyPlugin = require("copy-webpack-plugin");
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
const minifyJson = require("@docspace/common/utils/minifyJson");
|
||||
const PrebuildWebpackPlugin = require("prebuild-webpack-plugin");
|
||||
const beforeBuild = require("@docspace/common/utils/beforeBuild");
|
||||
|
||||
const sharedDeps = require("@docspace/common/constants/sharedDependencies");
|
||||
const baseConfig = require("./webpack.base.js");
|
||||
@ -44,7 +46,7 @@ const clientConfig = {
|
||||
|
||||
folder += result.length === 0 ? "" : "/";
|
||||
|
||||
return `${folder}[name][ext]?hash=[contenthash]`; //`${folder}/[name].[contenthash][ext]`;
|
||||
return `static/${folder}[name][ext]?hash=[contenthash]`; //`${folder}/[name].[contenthash][ext]`;
|
||||
},
|
||||
},
|
||||
|
||||
@ -109,6 +111,17 @@ const clientConfig = {
|
||||
],
|
||||
}),
|
||||
new WebpackManifestPlugin(),
|
||||
new PrebuildWebpackPlugin({
|
||||
build: async (compiler, compilation, matchedFiles) => {
|
||||
await beforeBuild(
|
||||
[
|
||||
path.join(__dirname, "../public/locales"),
|
||||
path.join(__dirname, "../../../public/locales"),
|
||||
],
|
||||
path.join(__dirname, "../src/autoGeneratedTranslations.js")
|
||||
);
|
||||
},
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
|
@ -31,7 +31,7 @@ const serverConfig = {
|
||||
|
||||
folder += result.length === 0 ? "" : "/";
|
||||
|
||||
return `client/${folder}[name][ext]?hash=[contenthash]`; //`${folder}/[name].[contenthash][ext]`;
|
||||
return `/doceditor/static/${folder}[name][ext]?hash=[contenthash]`; //`${folder}/[name].[contenthash][ext]`;
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -87,6 +87,7 @@
|
||||
"nodemon": "^2.0.19",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"playwright": "^1.17.1",
|
||||
"prebuild-webpack-plugin": "^1.1.1",
|
||||
"sass": "^1.39.2",
|
||||
"sass-loader": "^12.1.0",
|
||||
"serve": "14.1.1",
|
||||
|
188
packages/login/src/autoGeneratedTranslations.ts
Normal file
188
packages/login/src/autoGeneratedTranslations.ts
Normal file
@ -0,0 +1,188 @@
|
||||
//THIS FILE IS AUTO GENERATED
|
||||
//DO NOT EDIT AND DELETE IT
|
||||
|
||||
import LoginazUrl from "ASSETS_DIR/locales/az/Login.json?url";
|
||||
import LoginbgUrl from "ASSETS_DIR/locales/bg/Login.json?url";
|
||||
import LogincsUrl from "ASSETS_DIR/locales/cs/Login.json?url";
|
||||
import LogindeUrl from "ASSETS_DIR/locales/de/Login.json?url";
|
||||
import LoginelGRUrl from "ASSETS_DIR/locales/el-GR/Login.json?url";
|
||||
import LoginenUrl from "ASSETS_DIR/locales/en/Login.json?url";
|
||||
import LoginesUrl from "ASSETS_DIR/locales/es/Login.json?url";
|
||||
import LoginfiUrl from "ASSETS_DIR/locales/fi/Login.json?url";
|
||||
import LoginfrUrl from "ASSETS_DIR/locales/fr/Login.json?url";
|
||||
import LoginitUrl from "ASSETS_DIR/locales/it/Login.json?url";
|
||||
import LoginjaJPUrl from "ASSETS_DIR/locales/ja-JP/Login.json?url";
|
||||
import LoginkoKRUrl from "ASSETS_DIR/locales/ko-KR/Login.json?url";
|
||||
import LoginloLAUrl from "ASSETS_DIR/locales/lo-LA/Login.json?url";
|
||||
import LoginlvUrl from "ASSETS_DIR/locales/lv/Login.json?url";
|
||||
import LoginnlUrl from "ASSETS_DIR/locales/nl/Login.json?url";
|
||||
import LoginplUrl from "ASSETS_DIR/locales/pl/Login.json?url";
|
||||
import LoginptUrl from "ASSETS_DIR/locales/pt/Login.json?url";
|
||||
import LoginptBRUrl from "ASSETS_DIR/locales/pt-BR/Login.json?url";
|
||||
import LoginroUrl from "ASSETS_DIR/locales/ro/Login.json?url";
|
||||
import LoginruUrl from "ASSETS_DIR/locales/ru/Login.json?url";
|
||||
import LoginskUrl from "ASSETS_DIR/locales/sk/Login.json?url";
|
||||
import LoginslUrl from "ASSETS_DIR/locales/sl/Login.json?url";
|
||||
import LogintrUrl from "ASSETS_DIR/locales/tr/Login.json?url";
|
||||
import LoginukUAUrl from "ASSETS_DIR/locales/uk-UA/Login.json?url";
|
||||
import LoginviUrl from "ASSETS_DIR/locales/vi/Login.json?url";
|
||||
import LoginzhCNUrl from "ASSETS_DIR/locales/zh-CN/Login.json?url";
|
||||
import CommonazUrl from "PUBLIC_DIR/locales/az/Common.json?url";
|
||||
import CommonbgUrl from "PUBLIC_DIR/locales/bg/Common.json?url";
|
||||
import CommoncsUrl from "PUBLIC_DIR/locales/cs/Common.json?url";
|
||||
import CommondeUrl from "PUBLIC_DIR/locales/de/Common.json?url";
|
||||
import CommonelGRUrl from "PUBLIC_DIR/locales/el-GR/Common.json?url";
|
||||
import CommonenUrl from "PUBLIC_DIR/locales/en/Common.json?url";
|
||||
import CommonesUrl from "PUBLIC_DIR/locales/es/Common.json?url";
|
||||
import CommonfiUrl from "PUBLIC_DIR/locales/fi/Common.json?url";
|
||||
import CommonfrUrl from "PUBLIC_DIR/locales/fr/Common.json?url";
|
||||
import CommonitUrl from "PUBLIC_DIR/locales/it/Common.json?url";
|
||||
import CommonjaJPUrl from "PUBLIC_DIR/locales/ja-JP/Common.json?url";
|
||||
import CommonkoKRUrl from "PUBLIC_DIR/locales/ko-KR/Common.json?url";
|
||||
import CommonloLAUrl from "PUBLIC_DIR/locales/lo-LA/Common.json?url";
|
||||
import CommonlvUrl from "PUBLIC_DIR/locales/lv/Common.json?url";
|
||||
import CommonnlUrl from "PUBLIC_DIR/locales/nl/Common.json?url";
|
||||
import CommonplUrl from "PUBLIC_DIR/locales/pl/Common.json?url";
|
||||
import CommonptUrl from "PUBLIC_DIR/locales/pt/Common.json?url";
|
||||
import CommonptBRUrl from "PUBLIC_DIR/locales/pt-BR/Common.json?url";
|
||||
import CommonroUrl from "PUBLIC_DIR/locales/ro/Common.json?url";
|
||||
import CommonruUrl from "PUBLIC_DIR/locales/ru/Common.json?url";
|
||||
import CommonskUrl from "PUBLIC_DIR/locales/sk/Common.json?url";
|
||||
import CommonslUrl from "PUBLIC_DIR/locales/sl/Common.json?url";
|
||||
import CommontrUrl from "PUBLIC_DIR/locales/tr/Common.json?url";
|
||||
import CommonukUAUrl from "PUBLIC_DIR/locales/uk-UA/Common.json?url";
|
||||
import CommonviUrl from "PUBLIC_DIR/locales/vi/Common.json?url";
|
||||
import CommonzhCNUrl from "PUBLIC_DIR/locales/zh-CN/Common.json?url";
|
||||
|
||||
const az = new Map([
|
||||
["Login", LoginazUrl],
|
||||
["Common", CommonazUrl]
|
||||
]);
|
||||
const bg = new Map([
|
||||
["Login", LoginbgUrl],
|
||||
["Common", CommonbgUrl]
|
||||
]);
|
||||
const cs = new Map([
|
||||
["Login", LogincsUrl],
|
||||
["Common", CommoncsUrl]
|
||||
]);
|
||||
const de = new Map([
|
||||
["Login", LogindeUrl],
|
||||
["Common", CommondeUrl]
|
||||
]);
|
||||
const elGR = new Map([
|
||||
["Login", LoginelGRUrl],
|
||||
["Common", CommonelGRUrl]
|
||||
]);
|
||||
const en = new Map([
|
||||
["Login", LoginenUrl],
|
||||
["Common", CommonenUrl]
|
||||
]);
|
||||
const es = new Map([
|
||||
["Login", LoginesUrl],
|
||||
["Common", CommonesUrl]
|
||||
]);
|
||||
const fi = new Map([
|
||||
["Login", LoginfiUrl],
|
||||
["Common", CommonfiUrl]
|
||||
]);
|
||||
const fr = new Map([
|
||||
["Login", LoginfrUrl],
|
||||
["Common", CommonfrUrl]
|
||||
]);
|
||||
const it = new Map([
|
||||
["Login", LoginitUrl],
|
||||
["Common", CommonitUrl]
|
||||
]);
|
||||
const jaJP = new Map([
|
||||
["Login", LoginjaJPUrl],
|
||||
["Common", CommonjaJPUrl]
|
||||
]);
|
||||
const koKR = new Map([
|
||||
["Login", LoginkoKRUrl],
|
||||
["Common", CommonkoKRUrl]
|
||||
]);
|
||||
const loLA = new Map([
|
||||
["Login", LoginloLAUrl],
|
||||
["Common", CommonloLAUrl]
|
||||
]);
|
||||
const lv = new Map([
|
||||
["Login", LoginlvUrl],
|
||||
["Common", CommonlvUrl]
|
||||
]);
|
||||
const nl = new Map([
|
||||
["Login", LoginnlUrl],
|
||||
["Common", CommonnlUrl]
|
||||
]);
|
||||
const pl = new Map([
|
||||
["Login", LoginplUrl],
|
||||
["Common", CommonplUrl]
|
||||
]);
|
||||
const pt = new Map([
|
||||
["Login", LoginptUrl],
|
||||
["Common", CommonptUrl]
|
||||
]);
|
||||
const ptBR = new Map([
|
||||
["Login", LoginptBRUrl],
|
||||
["Common", CommonptBRUrl]
|
||||
]);
|
||||
const ro = new Map([
|
||||
["Login", LoginroUrl],
|
||||
["Common", CommonroUrl]
|
||||
]);
|
||||
const ru = new Map([
|
||||
["Login", LoginruUrl],
|
||||
["Common", CommonruUrl]
|
||||
]);
|
||||
const sk = new Map([
|
||||
["Login", LoginskUrl],
|
||||
["Common", CommonskUrl]
|
||||
]);
|
||||
const sl = new Map([
|
||||
["Login", LoginslUrl],
|
||||
["Common", CommonslUrl]
|
||||
]);
|
||||
const tr = new Map([
|
||||
["Login", LogintrUrl],
|
||||
["Common", CommontrUrl]
|
||||
]);
|
||||
const ukUA = new Map([
|
||||
["Login", LoginukUAUrl],
|
||||
["Common", CommonukUAUrl]
|
||||
]);
|
||||
const vi = new Map([
|
||||
["Login", LoginviUrl],
|
||||
["Common", CommonviUrl]
|
||||
]);
|
||||
const zhCN = new Map([
|
||||
["Login", LoginzhCNUrl],
|
||||
["Common", CommonzhCNUrl]
|
||||
]);
|
||||
export const translations = new Map([
|
||||
["az", az],
|
||||
["bg", bg],
|
||||
["cs", cs],
|
||||
["de", de],
|
||||
["el-GR", elGR],
|
||||
["en", en],
|
||||
["es", es],
|
||||
["fi", fi],
|
||||
["fr", fr],
|
||||
["it", it],
|
||||
["ja-JP", jaJP],
|
||||
["ko-KR", koKR],
|
||||
["lo-LA", loLA],
|
||||
["lv", lv],
|
||||
["nl", nl],
|
||||
["pl", pl],
|
||||
["pt", pt],
|
||||
["pt-BR", ptBR],
|
||||
["ro", ro],
|
||||
["ru", ru],
|
||||
["sk", sk],
|
||||
["sl", sl],
|
||||
["tr", tr],
|
||||
["uk-UA", ukUA],
|
||||
["vi", vi],
|
||||
["zh-CN", zhCN],
|
||||
]);
|
@ -1,6 +1,6 @@
|
||||
import React from "react";
|
||||
import { hydrate } from "react-dom";
|
||||
import { registerSW } from "@docspace/common/sw/helper";
|
||||
// import { registerSW } from "@docspace/common/sw/helper";
|
||||
import pkg from "../../package.json";
|
||||
import { initI18n } from "./helpers/utils";
|
||||
import ClientApp from "./components/ClientApp";
|
||||
@ -55,4 +55,4 @@ if (IS_DEVELOPMENT) {
|
||||
};
|
||||
}
|
||||
|
||||
registerSW();
|
||||
// registerSW();
|
||||
|
@ -73,8 +73,8 @@ const Form: React.FC = ({ theme, setTheme, logoUrls }) => {
|
||||
|
||||
const logo = Object.values(logoUrls)[1];
|
||||
const logoUrl = !theme?.isBase
|
||||
? getLogoFromPath(logo?.path?.dark).replace("client/", "/login/")
|
||||
: getLogoFromPath(logo?.path?.light).replace("client/", "/login/");
|
||||
? getLogoFromPath(logo?.path?.dark)
|
||||
: getLogoFromPath(logo?.path?.light);
|
||||
|
||||
return (
|
||||
<LoginContainer id="code-page" theme={theme}>
|
||||
@ -135,10 +135,7 @@ const Form: React.FC = ({ theme, setTheme, logoUrls }) => {
|
||||
};
|
||||
|
||||
const CodeLogin: React.FC<ICodeProps> = (props) => {
|
||||
const bgPattern = getBgPattern(props.currentColorScheme.id).replace(
|
||||
"client/",
|
||||
"/login/"
|
||||
);
|
||||
const bgPattern = getBgPattern(props.currentColorScheme.id);
|
||||
const mounted = useMounted();
|
||||
|
||||
if (!mounted) return <></>;
|
||||
|
@ -187,15 +187,12 @@ const Login: React.FC<ILoginProps> = ({
|
||||
setRecoverDialogVisible(!recoverDialogVisible);
|
||||
};
|
||||
|
||||
const bgPattern = getBgPattern(currentColorScheme.id).replace(
|
||||
"client/",
|
||||
"login/"
|
||||
);
|
||||
const bgPattern = getBgPattern(currentColorScheme.id);
|
||||
|
||||
const logo = Object.values(logoUrls)[1];
|
||||
const logoUrl = !theme.isBase
|
||||
? getLogoFromPath(logo.path.dark).replace("client/", "login/")
|
||||
: getLogoFromPath(logo.path.light).replace("client/", "login/");
|
||||
? getLogoFromPath(logo.path.dark)
|
||||
: getLogoFromPath(logo.path.light);
|
||||
|
||||
if (!mounted) return <></>;
|
||||
if (isRestoringPortal) return <></>;
|
||||
|
@ -26,8 +26,8 @@ const SimpleNav = ({ theme, logoUrls }) => {
|
||||
const logo = Object.values(logoUrls)[0];
|
||||
|
||||
const logoUrl = !theme.isBase
|
||||
? getLogoFromPath(logo.path.dark).replace("client/", "/login/")
|
||||
: getLogoFromPath(logo.path.light).replace("client/", "/login/");
|
||||
? getLogoFromPath(logo.path.dark)
|
||||
: getLogoFromPath(logo.path.light);
|
||||
|
||||
return (
|
||||
<StyledNav id="login-header" theme={theme}>
|
||||
|
@ -1,10 +1,48 @@
|
||||
import { translations } from "../../autoGeneratedTranslations";
|
||||
import pkg from "../../../package.json";
|
||||
import { thirdPartyLogin } from "@docspace/common/utils/loginUtils";
|
||||
|
||||
export function getLanguage(lng: string) {
|
||||
try {
|
||||
let language = lng == "en-US" || lng == "en-GB" ? "en" : lng;
|
||||
|
||||
const splitted = lng.split("-");
|
||||
|
||||
if (splitted.length == 2 && splitted[0] == splitted[1].toLowerCase()) {
|
||||
language = splitted[0];
|
||||
}
|
||||
|
||||
return language;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
return lng;
|
||||
}
|
||||
|
||||
export function loadLanguagePath(homepage: string, fixedNS = null) {
|
||||
return (lng: string | [string], ns: string) => {
|
||||
const language = getLanguage(lng instanceof Array ? lng[0] : lng);
|
||||
|
||||
const lngCollection = translations.get(language);
|
||||
|
||||
const path = lngCollection?.get(`${fixedNS || ns}`);
|
||||
|
||||
if (!path) return `/login/locales/${language}/${fixedNS || ns}.json`;
|
||||
|
||||
const isCommonPath = path?.indexOf("Common") > -1;
|
||||
|
||||
if (ns.length > 0 && ns[0] === "Common" && isCommonPath) {
|
||||
return path.replace("/login/", "/static/");
|
||||
}
|
||||
|
||||
return path;
|
||||
};
|
||||
}
|
||||
|
||||
export function initI18n(initialI18nStoreASC: IInitialI18nStoreASC): void {
|
||||
if (!initialI18nStoreASC || window.i18n) return;
|
||||
|
||||
const { homepage } = pkg;
|
||||
|
||||
const i18n = {
|
||||
inLoad: [],
|
||||
loaded: {},
|
||||
@ -12,17 +50,28 @@ export function initI18n(initialI18nStoreASC: IInitialI18nStoreASC): void {
|
||||
window.i18n = i18n;
|
||||
|
||||
for (let lng in initialI18nStoreASC) {
|
||||
const collection = translations.get(lng);
|
||||
|
||||
for (let ns in initialI18nStoreASC[lng]) {
|
||||
if (ns === "Common") {
|
||||
window.i18n.loaded[`/static/locales/${lng}/${ns}.json`] = {
|
||||
const path = collection?.get(ns);
|
||||
|
||||
if (!path) {
|
||||
window.i18n.loaded[`/login/locales/${lng}/${ns}.json`] = {
|
||||
namespaces: ns,
|
||||
data: initialI18nStoreASC[lng][ns],
|
||||
};
|
||||
} else {
|
||||
window.i18n.loaded[`${homepage}/locales/${lng}/${ns}.json`] = {
|
||||
namespaces: ns,
|
||||
data: initialI18nStoreASC[lng][ns],
|
||||
};
|
||||
if (ns === "Common") {
|
||||
window.i18n.loaded[`${path?.replace("/login/", "/static/")}`] = {
|
||||
namespaces: ns,
|
||||
data: initialI18nStoreASC[lng][ns],
|
||||
};
|
||||
} else {
|
||||
window.i18n.loaded[`${path}`] = {
|
||||
namespaces: ns,
|
||||
data: initialI18nStoreASC[lng][ns],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,8 @@ import { initReactI18next } from "react-i18next";
|
||||
import Backend from "@docspace/common/utils/i18next-http-backend";
|
||||
import config from "../../package.json";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import { loadLanguagePath, getCookie } from "@docspace/common/utils";
|
||||
import { getCookie } from "@docspace/common/utils";
|
||||
import { loadLanguagePath } from "./helpers/utils";
|
||||
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
|
@ -12,6 +12,7 @@ import i18nextMiddleware from "i18next-express-middleware";
|
||||
import i18next from "./i18n";
|
||||
import cookieParser from "cookie-parser";
|
||||
import { LANGUAGE, COOKIE_EXPIRATION_YEAR } from "@docspace/common/constants";
|
||||
import { getLanguage } from "@docspace/common/utils";
|
||||
import { initSSR } from "@docspace/common/api/client";
|
||||
import dns from "dns";
|
||||
|
||||
@ -66,6 +67,8 @@ app.get("*", async (req: ILoginRequest, res: Response, next) => {
|
||||
});
|
||||
}
|
||||
|
||||
currentLanguage = getLanguage(currentLanguage);
|
||||
|
||||
if (i18n) await i18n.changeLanguage(currentLanguage);
|
||||
|
||||
let initialI18nStore = {};
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { translations } from "../../../autoGeneratedTranslations";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import {
|
||||
@ -37,18 +38,9 @@ export const getScripts = (assets: assetsType): string[] | void => {
|
||||
};
|
||||
|
||||
export const loadPath = (language: string, nameSpace: string): string => {
|
||||
let resourcePath = path.resolve(
|
||||
path.join(__dirname, "client", `locales/${language}/${nameSpace}.json`)
|
||||
);
|
||||
if (nameSpace === "Common")
|
||||
resourcePath = path.resolve(
|
||||
path.join(
|
||||
__dirname,
|
||||
`../../../public/locales/${language}/${nameSpace}.json`
|
||||
)
|
||||
);
|
||||
const path = translations?.get(language)?.get(nameSpace);
|
||||
|
||||
return resourcePath;
|
||||
return path;
|
||||
};
|
||||
|
||||
export const getInitialState = async (
|
||||
|
@ -2,6 +2,13 @@ import { getScripts } from "./helpers";
|
||||
import pkg from "../../../package.json";
|
||||
import { getLogoFromPath } from "@docspace/common/utils";
|
||||
|
||||
import firstFont from "PUBLIC_DIR/fonts/RjgO7rYTmqiVp7vzi-Q5URJtnKITppOI_IvcXXDNrsc.woff2";
|
||||
import secondFont from "PUBLIC_DIR/fonts/MTP_ySUJH_bn48VBG8sNSugdm0LZdjqr5-oayXSOefg.woff2";
|
||||
import thirdFont from "PUBLIC_DIR/fonts/k3k702ZOKiLJc3WVjuplzOgdm0LZdjqr5-oayXSOefg.woff2";
|
||||
import fourthFont from "PUBLIC_DIR/fonts/cJZKeOuBrn4kERxqtaUH3VtXRa8TVwTICgirnJhmVJw.woff2";
|
||||
import fifthFont from "PUBLIC_DIR/fonts/MTP_ySUJH_bn48VBG8sNSpX5f-9o1vgP2EXwfjgl7AY.woff2";
|
||||
import sixthFont from "PUBLIC_DIR/fonts/k3k702ZOKiLJc3WVjuplzJX5f-9o1vgP2EXwfjgl7AY.woff2";
|
||||
|
||||
const { title } = pkg;
|
||||
const organizationName = "ONLYOFFICE"; //TODO: Replace to API variant
|
||||
|
||||
@ -28,9 +35,7 @@ const template: Template = (
|
||||
? `${t("Authorization")} – ${organizationName}`
|
||||
: title;
|
||||
|
||||
const favicon = getLogoFromPath(
|
||||
initLoginState.logoUrls[2]?.path?.light
|
||||
).replace("client/", "login/");
|
||||
const favicon = getLogoFromPath(initLoginState.logoUrls[2]?.path?.light);
|
||||
|
||||
let clientScripts =
|
||||
assets && assets.hasOwnProperty("client.js")
|
||||
@ -88,12 +93,12 @@ const template: Template = (
|
||||
content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=no, viewport-fit=cover"
|
||||
/>
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<link rel="preload" as="font" crossorigin type="font/woff2" href="/static/fonts/RjgO7rYTmqiVp7vzi-Q5URJtnKITppOI_IvcXXDNrsc.woff2" />
|
||||
<link rel="preload" as="font" crossorigin type="font/woff2" href="/static/fonts/MTP_ySUJH_bn48VBG8sNSugdm0LZdjqr5-oayXSOefg.woff2" />
|
||||
<link rel="preload" as="font" crossorigin type="font/woff2" href="/static/fonts/k3k702ZOKiLJc3WVjuplzOgdm0LZdjqr5-oayXSOefg.woff2" />
|
||||
<link rel="preload" as="font" crossorigin type="font/woff2" href="/static/fonts/cJZKeOuBrn4kERxqtaUH3VtXRa8TVwTICgirnJhmVJw.woff2" />
|
||||
<link rel="preload" as="font" crossorigin type="font/woff2" href="/static/fonts/MTP_ySUJH_bn48VBG8sNSpX5f-9o1vgP2EXwfjgl7AY.woff2" />
|
||||
<link rel="preload" as="font" crossorigin type="font/woff2" href="/static/fonts/k3k702ZOKiLJc3WVjuplzJX5f-9o1vgP2EXwfjgl7AY.woff2" />
|
||||
<link rel="preload" as="font" crossorigin type="font/woff2" href="${firstFont}" />
|
||||
<link rel="preload" as="font" crossorigin type="font/woff2" href="${secondFont}" />
|
||||
<link rel="preload" as="font" crossorigin type="font/woff2" href="${thirdFont}" />
|
||||
<link rel="preload" as="font" crossorigin type="font/woff2" href="${fourthFont}" />
|
||||
<link rel="preload" as="font" crossorigin type="font/woff2" href="${fifthFont}" />
|
||||
<link rel="preload" as="font" crossorigin type="font/woff2" href="${sixthFont}" />
|
||||
|
||||
<link id="favicon" rel="shortcut icon" href=${favicon} />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
|
@ -14,6 +14,7 @@ module.exports = {
|
||||
},
|
||||
alias: {
|
||||
PUBLIC_DIR: path.resolve(__dirname, "../../../public"),
|
||||
ASSETS_DIR: path.resolve(__dirname, "../public"),
|
||||
SRC_DIR: path.resolve(__dirname, "../src"),
|
||||
PACKAGE_FILE: path.resolve(__dirname, "../package.json"),
|
||||
},
|
||||
@ -44,15 +45,24 @@ module.exports = {
|
||||
},
|
||||
{
|
||||
test: fontsExtension,
|
||||
type: "asset",
|
||||
generator: {
|
||||
emit: false,
|
||||
},
|
||||
type: "asset/resource",
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|ico)$/i,
|
||||
generator: {
|
||||
emit: false,
|
||||
},
|
||||
type: "asset/resource",
|
||||
},
|
||||
{
|
||||
test: /\.svg$/i,
|
||||
type: "asset/resource",
|
||||
generator: {
|
||||
emit: false,
|
||||
},
|
||||
resourceQuery: /url/, // *.svg?url
|
||||
},
|
||||
{
|
||||
@ -72,6 +82,9 @@ module.exports = {
|
||||
},
|
||||
{
|
||||
test: imageExtensions,
|
||||
generator: {
|
||||
emit: false,
|
||||
},
|
||||
type: "asset/resource",
|
||||
},
|
||||
],
|
||||
|
@ -11,6 +11,8 @@ const TerserPlugin = require("terser-webpack-plugin");
|
||||
const combineUrl = require("@docspace/common/utils/combineUrl");
|
||||
const minifyJson = require("@docspace/common/utils/minifyJson");
|
||||
const sharedDeps = require("@docspace/common/constants/sharedDependencies");
|
||||
const PrebuildWebpackPlugin = require("prebuild-webpack-plugin");
|
||||
const beforeBuild = require("@docspace/common/utils/beforeBuild");
|
||||
const baseConfig = require("./webpack.base.js");
|
||||
const pkg = require("../package.json");
|
||||
const deps = pkg.dependencies || {};
|
||||
@ -44,7 +46,7 @@ const clientConfig = {
|
||||
|
||||
folder += result.length === 0 ? "" : "/";
|
||||
|
||||
return `${folder}[name][ext]?hash=[contenthash]`; // `${folder}/[name].[contenthash][ext]`;
|
||||
return `static/${folder}[name][ext]?hash=[contenthash]`; // `${folder}/[name].[contenthash][ext]`;
|
||||
},
|
||||
},
|
||||
|
||||
@ -82,6 +84,33 @@ const clientConfig = {
|
||||
"sass-loader",
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.json$/,
|
||||
resourceQuery: /url/,
|
||||
type: "javascript/auto",
|
||||
use: [
|
||||
{
|
||||
loader: "file-loader",
|
||||
|
||||
options: {
|
||||
emitFile: false,
|
||||
name: (resourcePath, resourceQuery) => {
|
||||
let result = resourcePath
|
||||
.split(`public${path.sep}`)[1]
|
||||
.split(path.sep);
|
||||
|
||||
result.pop();
|
||||
|
||||
let folder = result.join("/");
|
||||
|
||||
folder += result.length === 0 ? "" : "/";
|
||||
|
||||
return `${folder}[name].[ext]?hash=[contenthash]`; // `${folder}/[name].[contenthash][ext]`;
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@ -110,6 +139,17 @@ const clientConfig = {
|
||||
],
|
||||
}),
|
||||
new WebpackManifestPlugin(),
|
||||
new PrebuildWebpackPlugin({
|
||||
build: async (compiler, compilation, matchedFiles) => {
|
||||
await beforeBuild(
|
||||
[
|
||||
path.join(__dirname, "../public/locales"),
|
||||
path.join(__dirname, "../../../public/locales"),
|
||||
],
|
||||
path.join(__dirname, "../src/autoGeneratedTranslations.ts")
|
||||
);
|
||||
},
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
|
@ -31,10 +31,42 @@ const serverConfig = {
|
||||
|
||||
folder += result.length === 0 ? "" : "/";
|
||||
|
||||
return `client/${folder}[name][ext]?hash=[contenthash]`; //`${folder}/[name].[contenthash][ext]`;
|
||||
return `/login/static/${folder}[name][ext]?hash=[contenthash]`; //`${folder}/[name].[contenthash][ext]`;
|
||||
},
|
||||
},
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.json$/,
|
||||
resourceQuery: /url/,
|
||||
type: "javascript/auto",
|
||||
use: [
|
||||
{
|
||||
loader: "file-loader",
|
||||
|
||||
options: {
|
||||
emitFile: false,
|
||||
name: (resourcePath) => {
|
||||
let result = resourcePath
|
||||
.split(`public${path.sep}`)[1]
|
||||
.split(path.sep);
|
||||
|
||||
result.pop();
|
||||
|
||||
let folder = result.join("/");
|
||||
|
||||
folder += result.length === 0 ? "" : "/";
|
||||
|
||||
return `client/${folder}[name].[ext]?hash=[contenthash]`; // `${folder}/[name].[contenthash][ext]`;
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new CopyPlugin({
|
||||
patterns: [
|
||||
|
@ -892,7 +892,7 @@ public class FileStorageService<T> //: IFileStorageService
|
||||
{
|
||||
var pathThumb = $"{path}{fileExt.Trim('.')}.{size.Width}x{size.Height}.{_global.ThumbnailExtension}";
|
||||
|
||||
if (await storeTemplate.IsFileAsync("", pathThumb))
|
||||
if (!await storeTemplate.IsFileAsync("", pathThumb))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -43,11 +43,20 @@ public class ThumbnailSettings
|
||||
set => _serverRoot = value;
|
||||
}
|
||||
|
||||
private int _launchFrequency;
|
||||
public int LaunchFrequency
|
||||
private int _boundedChannelCapacity;
|
||||
|
||||
public int BoundedChannelCapacity
|
||||
{
|
||||
get => _launchFrequency != 0 ? _launchFrequency : 15;
|
||||
set => _launchFrequency = value;
|
||||
get => _boundedChannelCapacity != 0 ? _boundedChannelCapacity : MaxDegreeOfParallelism * 10;
|
||||
set => _boundedChannelCapacity = value;
|
||||
}
|
||||
|
||||
private int _batchSize;
|
||||
|
||||
public int BatchSize
|
||||
{
|
||||
get => _batchSize != 0 ? _batchSize : MaxDegreeOfParallelism * 10;
|
||||
set => _batchSize = value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -89,8 +89,11 @@ internal class FileConverterService<T> : BackgroundService
|
||||
fileConverterQueue = scope.ServiceProvider.GetService<FileConverterQueue<T>>();
|
||||
|
||||
var _conversionQueue = fileConverterQueue.GetAllTask().ToList();
|
||||
|
||||
logger.DebugRunCheckConvertFilesStatus(_conversionQueue.Count);
|
||||
|
||||
if (_conversionQueue.Count > 0)
|
||||
{
|
||||
logger.DebugRunCheckConvertFilesStatus(_conversionQueue.Count);
|
||||
}
|
||||
|
||||
var filesIsConverting = _conversionQueue
|
||||
.Where(x => string.IsNullOrEmpty(x.Processed))
|
||||
|
@ -48,6 +48,9 @@ internal static partial class BuilderLogger
|
||||
[LoggerMessage(Level = LogLevel.Debug, Message = "CropImage: FileId: {fileId}. Successfully saved.")]
|
||||
public static partial void DebugCropImageSuccessfullySaved(this ILogger logger, string fileId);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Warning, Message = "MakeThumbnail: FileId: {fileId}, ThumbnailUrl: {url}, ResultPercent: {percent}, Attempt: {attempt}. Exception in process generate document thumbnails")]
|
||||
public static partial void WarningMakeThumbnail(this ILogger logger, string fileId, string url, int percent, int attempt, Exception exception);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Error, Message = "BuildThumbnails: filesWithoutThumbnails.Count: {count}.")]
|
||||
public static partial void ErrorBuildThumbnailsCount(this ILogger logger, int count, Exception exception);
|
||||
|
||||
|
@ -24,6 +24,8 @@
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
using System.Threading.Channels;
|
||||
|
||||
namespace ASC.Files.Service;
|
||||
public class Startup : BaseWorkerStartup
|
||||
{
|
||||
@ -65,9 +67,7 @@ public class Startup : BaseWorkerStartup
|
||||
|
||||
services.AddHostedService<FeedCleanerService>();
|
||||
DIHelper.TryAdd<FeedCleanerService>();
|
||||
|
||||
DIHelper.TryAdd<FileDataQueue>();
|
||||
|
||||
|
||||
services.AddActivePassiveHostedService<FileConverterService<int>>();
|
||||
DIHelper.TryAdd<FileConverterService<int>>();
|
||||
|
||||
@ -93,6 +93,9 @@ public class Startup : BaseWorkerStartup
|
||||
DIHelper.TryAdd<UserManager>();
|
||||
DIHelper.TryAdd<SocketServiceClient>();
|
||||
DIHelper.TryAdd<FileStorageService<int>>();
|
||||
DIHelper.TryAdd<FileDataProvider>();
|
||||
DIHelper.TryAdd<BuilderQueue<int>>();
|
||||
DIHelper.TryAdd<Builder<int>>();
|
||||
|
||||
services.AddScoped<ITenantQuotaFeatureChecker, CountRoomChecker>();
|
||||
services.AddScoped<CountRoomChecker>();
|
||||
@ -103,12 +106,20 @@ public class Startup : BaseWorkerStartup
|
||||
services.AddScoped<UsersInRoomChecker>();
|
||||
|
||||
services.AddScoped<ITenantQuotaFeatureStat<UsersInRoomFeature, int>, UsersInRoomStatistic>();
|
||||
|
||||
services.AddScoped<UsersInRoomStatistic>();
|
||||
|
||||
|
||||
|
||||
services.AddBaseDbContextPool<FilesDbContext>();
|
||||
|
||||
|
||||
services.AddBaseDbContextPool<FilesDbContext>();
|
||||
|
||||
if (!int.TryParse(_configuration["thumbnail:boundedChannelCapacity"], out var boundedChannelCapacity))
|
||||
{
|
||||
boundedChannelCapacity = 100;
|
||||
}
|
||||
|
||||
services.AddSingleton(Channel.CreateBounded<IEnumerable<FileData<int>>>(new BoundedChannelOptions(boundedChannelCapacity) { SingleReader = true, SingleWriter = false }));
|
||||
services.AddSingleton(svc => svc.GetRequiredService<Channel<IEnumerable<FileData<int>>>>().Reader);
|
||||
services.AddSingleton(svc => svc.GetRequiredService<Channel<IEnumerable<FileData<int>>>>().Writer);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -46,6 +46,17 @@ public class BuilderQueue<T>
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var scope = _serviceScopeFactory.CreateAsyncScope();
|
||||
|
||||
var fileDataProvider = scope.ServiceProvider.GetService<FileDataProvider>();
|
||||
|
||||
var premiumTenants = fileDataProvider.GetPremiumTenants();
|
||||
|
||||
filesWithoutThumbnails = filesWithoutThumbnails
|
||||
.OrderByDescending(fileData => Array.IndexOf(premiumTenants, fileData.TenantId))
|
||||
.ToList();
|
||||
|
||||
|
||||
await Parallel.ForEachAsync(
|
||||
filesWithoutThumbnails,
|
||||
new ParallelOptions { MaxDegreeOfParallelism = _config.MaxDegreeOfParallelism },
|
||||
@ -141,11 +152,7 @@ public class Builder<T>
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.ErrorBuildThumbnailsTenantId(fileData.TenantId, exception);
|
||||
}
|
||||
finally
|
||||
{
|
||||
FileDataQueue.Queue.TryRemove(fileData.FileId, out _);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task GenerateThumbnail(IFileDao<T> fileDao, FileData<T> fileData)
|
||||
@ -240,22 +247,22 @@ public class Builder<T>
|
||||
private async Task MakeThumbnail(IFileDao<T> fileDao, File<T> file)
|
||||
{
|
||||
await fileDao.SetThumbnailStatusAsync(file, Core.Thumbnail.Creating);
|
||||
|
||||
|
||||
foreach (var w in _config.Sizes)
|
||||
{
|
||||
_logger.DebugMakeThumbnail1(file.Id.ToString());
|
||||
|
||||
string thumbnailUrl = null;
|
||||
var resultPercent = 0;
|
||||
var attempt = 1;
|
||||
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
var (result, url) = await GetThumbnailUrl(file, _global.DocThumbnailExtension.ToString(), w.Width, w.Height);
|
||||
thumbnailUrl = url;
|
||||
|
||||
if (result)
|
||||
(resultPercent, thumbnailUrl) = await GetThumbnailUrl(file, _global.DocThumbnailExtension.ToString(), w.Width, w.Height);
|
||||
|
||||
if (resultPercent == 100)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -269,19 +276,27 @@ public class Builder<T>
|
||||
{
|
||||
if (documentServiceException.Code == DocumentServiceException.ErrorCode.ConvertPassword)
|
||||
{
|
||||
throw new Exception(string.Format("MakeThumbnail: FileId: {0}. Encrypted file.", file.Id));
|
||||
throw new Exception(String.Format("MakeThumbnail: FileId: {0}. Encrypted file.", file.Id), exception);
|
||||
}
|
||||
if (documentServiceException.Code == DocumentServiceException.ErrorCode.Convert)
|
||||
{
|
||||
throw new Exception(string.Format("MakeThumbnail: FileId: {0}. Could not convert.", file.Id));
|
||||
throw new Exception(String.Format("MakeThumbnail: FileId: {0}. Could not convert.", file.Id), exception);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.WarningMakeThumbnail(file.Id.ToString(), thumbnailUrl, resultPercent, attempt, exception);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.WarningMakeThumbnail(file.Id.ToString(), thumbnailUrl, resultPercent, attempt, exception);
|
||||
}
|
||||
}
|
||||
|
||||
if (attempt >= _config.AttemptsLimit)
|
||||
{
|
||||
throw new Exception(string.Format("MakeThumbnail: FileId: {0}. Attempts limmit exceeded.", file.Id));
|
||||
throw new Exception(string.Format("MakeThumbnail: FileId: {0}, ThumbnailUrl: {1}, ResultPercent: {2}. Attempts limmit exceeded.", file.Id, thumbnailUrl, resultPercent));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -300,7 +315,7 @@ public class Builder<T>
|
||||
|
||||
}
|
||||
|
||||
private async Task<(bool, string)> GetThumbnailUrl(File<T> file, string toExtension, int width, int height)
|
||||
private async Task<(int, string)> GetThumbnailUrl(File<T> file, string toExtension, int width, int height)
|
||||
{
|
||||
var fileUri = _pathProvider.GetFileStreamUrl(file);
|
||||
fileUri = _documentServiceConnector.ReplaceCommunityAdress(fileUri);
|
||||
@ -337,7 +352,7 @@ public class Builder<T>
|
||||
var (operationResultProgress, url) = await _documentServiceConnector.GetConvertedUriAsync(fileUri, fileExtension, toExtension, docKey, null, CultureInfo.CurrentCulture.Name, thumbnail, spreadsheetLayout, false);
|
||||
|
||||
operationResultProgress = Math.Min(operationResultProgress, 100);
|
||||
return (operationResultProgress == 100, url);
|
||||
return (operationResultProgress, url);
|
||||
}
|
||||
|
||||
private async Task SaveThumbnail(IFileDao<T> fileDao, File<T> file, string thumbnailUrl, int width, int height)
|
||||
|
@ -29,7 +29,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
namespace ASC.Files.ThumbnailBuilder;
|
||||
|
||||
[Scope]
|
||||
internal class FileDataProvider
|
||||
public class FileDataProvider
|
||||
{
|
||||
private readonly ThumbnailSettings _thumbnailSettings;
|
||||
private readonly ICache _cache;
|
||||
|
@ -1,34 +0,0 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Files.ThumbnailBuilder;
|
||||
|
||||
[Singletone(Additional = typeof(WorkerExtension))]
|
||||
public class FileDataQueue
|
||||
{
|
||||
internal static readonly ConcurrentDictionary<object, FileData<int>> Queue
|
||||
= new ConcurrentDictionary<object, FileData<int>>();
|
||||
}
|
@ -24,22 +24,34 @@
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
using System.Threading.Channels;
|
||||
|
||||
using ASC.Files.ThumbnailBuilder;
|
||||
|
||||
namespace ASC.Thumbnail.IntegrationEvents.EventHandling;
|
||||
|
||||
[Scope]
|
||||
public class ThumbnailRequestedIntegrationEventHandler : IIntegrationEventHandler<ThumbnailRequestedIntegrationEvent>
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly ILogger _logger;
|
||||
private readonly ChannelWriter<IEnumerable<FileData<int>>> _channelWriter;
|
||||
private readonly FileDataProvider _fileDataProvider;
|
||||
|
||||
private ThumbnailRequestedIntegrationEventHandler() : base()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ThumbnailRequestedIntegrationEventHandler(ILogger<ThumbnailRequestedIntegrationEventHandler> logger)
|
||||
public ThumbnailRequestedIntegrationEventHandler(
|
||||
ILogger<ThumbnailRequestedIntegrationEventHandler> logger,
|
||||
FileDataProvider fileDataProvider,
|
||||
ChannelWriter<IEnumerable<FileData<int>>> channelWriter)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
_logger = logger;
|
||||
_channelWriter = channelWriter;
|
||||
_fileDataProvider = fileDataProvider;
|
||||
}
|
||||
|
||||
|
||||
public async Task Handle(ThumbnailRequestedIntegrationEvent @event)
|
||||
{
|
||||
@ -47,14 +59,15 @@ public class ThumbnailRequestedIntegrationEventHandler : IIntegrationEventHandle
|
||||
{
|
||||
_logger.InformationHandlingIntegrationEvent(@event.Id, Program.AppName, @event);
|
||||
|
||||
foreach (var fileId in @event.FileIds)
|
||||
var freezingThumbnails = await _fileDataProvider.GetFreezingThumbnailsAsync();
|
||||
|
||||
var rawData = @event.FileIds.Select(fileId => new FileData<int>(@event.TenantId, Convert.ToInt32(fileId), @event.BaseUrl))
|
||||
.Union(freezingThumbnails);
|
||||
|
||||
if (await _channelWriter.WaitToWriteAsync())
|
||||
{
|
||||
var fileData = new FileData<int>(@event.TenantId, Convert.ToInt32(fileId), @event.BaseUrl);
|
||||
|
||||
FileDataQueue.Queue.TryAdd(fileId, fileData);
|
||||
await _channelWriter.WriteAsync(rawData);
|
||||
}
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,8 @@
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
using System.Threading.Channels;
|
||||
|
||||
namespace ASC.Files.ThumbnailBuilder;
|
||||
|
||||
[Singletone]
|
||||
@ -33,80 +35,49 @@ public class ThumbnailBuilderService : BackgroundService
|
||||
private readonly ThumbnailSettings _thumbnailSettings;
|
||||
private readonly ILogger<ThumbnailBuilderService> _logger;
|
||||
private readonly BuilderQueue<int> _builderQueue;
|
||||
private readonly ChannelReader<IEnumerable<FileData<int>>> _channelReader;
|
||||
|
||||
public ThumbnailBuilderService(
|
||||
BuilderQueue<int> builderQueue,
|
||||
IServiceScopeFactory serviceScopeFactory,
|
||||
ILogger<ThumbnailBuilderService> logger,
|
||||
ThumbnailSettings settings)
|
||||
ThumbnailSettings settings,
|
||||
ChannelReader<IEnumerable<FileData<int>>> channelReader)
|
||||
{
|
||||
_serviceScopeFactory = serviceScopeFactory;
|
||||
_thumbnailSettings = settings;
|
||||
_logger = logger;
|
||||
_builderQueue = builderQueue;
|
||||
_channelReader = channelReader;
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
_logger.InformationThumbnailWorkerRunnig();
|
||||
|
||||
stoppingToken.Register(() => _logger.InformationThumbnailWorkerStopping());
|
||||
|
||||
var fetchedData = new List<FileData<int>>();
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
await Procedure(stoppingToken);
|
||||
_logger.TraceProcedureStart();
|
||||
|
||||
await foreach (var rawData in _channelReader.ReadAllAsync(stoppingToken))
|
||||
{
|
||||
fetchedData.AddRange(rawData);
|
||||
|
||||
if (_channelReader.CanCount && _channelReader.Count > 0 && _thumbnailSettings.BatchSize >= fetchedData.Count())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
await _builderQueue.BuildThumbnails(fetchedData);
|
||||
|
||||
fetchedData = new List<FileData<int>>();
|
||||
}
|
||||
}
|
||||
|
||||
_logger.InformationThumbnailWorkerStopping();
|
||||
}
|
||||
|
||||
private async Task Procedure(CancellationToken stoppingToken)
|
||||
{
|
||||
_logger.TraceProcedureStart();
|
||||
|
||||
if (stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//var configSection = (ConfigSection)ConfigurationManager.GetSection("thumbnailBuilder") ?? new ConfigSection();
|
||||
//CommonLinkUtility.Initialize(configSection.ServerRoot, false);
|
||||
|
||||
await using (var scope = _serviceScopeFactory.CreateAsyncScope())
|
||||
{
|
||||
var fileDataProvider = scope.ServiceProvider.GetService<FileDataProvider>();
|
||||
|
||||
var filesWithoutThumbnails = FileDataQueue.Queue.Select(pair => pair.Value)
|
||||
.ToList();
|
||||
|
||||
filesWithoutThumbnails.AddRange(await fileDataProvider.GetFreezingThumbnailsAsync());
|
||||
|
||||
if (filesWithoutThumbnails.Count == 0)
|
||||
{
|
||||
_logger.TraceProcedureWaiting(_thumbnailSettings.LaunchFrequency);
|
||||
|
||||
await Task.Delay(TimeSpan.FromSeconds(_thumbnailSettings.LaunchFrequency), stoppingToken);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var premiumTenants = fileDataProvider.GetPremiumTenants();
|
||||
|
||||
filesWithoutThumbnails = filesWithoutThumbnails
|
||||
.OrderByDescending(fileData => Array.IndexOf(premiumTenants, fileData.TenantId))
|
||||
.ToList();
|
||||
|
||||
await _builderQueue.BuildThumbnails(filesWithoutThumbnails);
|
||||
}
|
||||
|
||||
_logger.TraceProcedureFinish();
|
||||
}
|
||||
}
|
||||
|
||||
public static class WorkerExtension
|
||||
{
|
||||
public static void Register(DIHelper services)
|
||||
{
|
||||
services.TryAdd<FileDataProvider>();
|
||||
services.TryAdd<BuilderQueue<int>>();
|
||||
services.TryAdd<Builder<int>>();
|
||||
}
|
||||
}
|
16
yarn.lock
16
yarn.lock
@ -2798,6 +2798,7 @@ __metadata:
|
||||
html-webpack-plugin: 5.3.2
|
||||
json-loader: ^0.5.7
|
||||
playwright: ^1.18.1
|
||||
prebuild-webpack-plugin: ^1.1.1
|
||||
react-avatar-editor: ^13.0.0
|
||||
react-colorful: ^5.5.1
|
||||
react-hotkeys-hook: ^3.4.4
|
||||
@ -2987,6 +2988,7 @@ __metadata:
|
||||
nconf: ^0.12.0
|
||||
nodemon: ^2.0.7
|
||||
npm-run-all: ^4.1.5
|
||||
prebuild-webpack-plugin: ^1.1.1
|
||||
sass: ^1.53.0
|
||||
sass-loader: ^13.0.2
|
||||
shx: ^0.3.4
|
||||
@ -3061,6 +3063,7 @@ __metadata:
|
||||
nodemon: ^2.0.19
|
||||
npm-run-all: ^4.1.5
|
||||
playwright: ^1.17.1
|
||||
prebuild-webpack-plugin: ^1.1.1
|
||||
sass: ^1.39.2
|
||||
sass-loader: ^12.1.0
|
||||
serve: 14.1.1
|
||||
@ -14030,7 +14033,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"glob@npm:^7.0.0, glob@npm:^7.0.3, glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.2.0":
|
||||
"glob@npm:^7.0.0, glob@npm:^7.0.3, glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.5, glob@npm:^7.1.6, glob@npm:^7.2.0":
|
||||
version: 7.2.3
|
||||
resolution: "glob@npm:7.2.3"
|
||||
dependencies:
|
||||
@ -20302,6 +20305,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prebuild-webpack-plugin@npm:^1.1.1":
|
||||
version: 1.1.1
|
||||
resolution: "prebuild-webpack-plugin@npm:1.1.1"
|
||||
dependencies:
|
||||
debug: ^4.1.1
|
||||
glob: ^7.1.5
|
||||
minimatch: ^3.0.4
|
||||
checksum: 11e091bbefc8e3dcda84c6abd1d02e250af4f4a5189355464bb5b440de2c6da722a55956b190ca6e4a4136684f0643d16c7d5c48a6eeae9b670409d62e1c6047
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prefix-style@npm:2.0.1":
|
||||
version: 2.0.1
|
||||
resolution: "prefix-style@npm:2.0.1"
|
||||
|
Loading…
Reference in New Issue
Block a user