mirror of
https://github.com/ONLYOFFICE/web-apps.git
synced 2026-02-10 18:05:32 +08:00
[Mobile] Add visio viewer
This commit is contained in:
12
apps/common/mobile/resources/css/skeleton.css
vendored
12
apps/common/mobile/resources/css/skeleton.css
vendored
@ -7,6 +7,7 @@ body.theme-type-light {
|
|||||||
--background-navbar-word: #446995;
|
--background-navbar-word: #446995;
|
||||||
--background-navbar-cell: #40865c;
|
--background-navbar-cell: #40865c;
|
||||||
--background-navbar-slide: #BE664F;
|
--background-navbar-slide: #BE664F;
|
||||||
|
--background-navbar-visio: #444796;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.theme-type-dark {
|
body.theme-type-dark {
|
||||||
@ -14,6 +15,7 @@ body.theme-type-dark {
|
|||||||
--background-navbar-word: #232323;
|
--background-navbar-word: #232323;
|
||||||
--background-navbar-cell: #232323;
|
--background-navbar-cell: #232323;
|
||||||
--background-navbar-slide: #232323;
|
--background-navbar-slide: #232323;
|
||||||
|
--background-navbar-visio: #232323;
|
||||||
|
|
||||||
background-color: var(--background-primary, #232323);
|
background-color: var(--background-primary, #232323);
|
||||||
}
|
}
|
||||||
@ -62,6 +64,10 @@ body.theme-type-dark {
|
|||||||
background-color: var(--background-navbar-slide, #BE664F);
|
background-color: var(--background-navbar-slide, #BE664F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.skl-navbar.skl-navbar--visio.skl-navbar--md {
|
||||||
|
background-color: var(--background-navbar-visio, #444796);
|
||||||
|
}
|
||||||
|
|
||||||
.skl-navbar::before {
|
.skl-navbar::before {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -162,3 +168,9 @@ body.theme-type-dark {
|
|||||||
--f7-subnavbar-bg-color: var(--background-navbar-slide, #BE664F);
|
--f7-subnavbar-bg-color: var(--background-navbar-slide, #BE664F);
|
||||||
--f7-subnavbar-height: 56px;
|
--f7-subnavbar-height: 56px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.md .visio-editor {
|
||||||
|
--f7-navbar-bg-color: var(--background-navbar-visio, #444796);
|
||||||
|
--f7-subnavbar-bg-color: var(--background-navbar-visio, #444796);
|
||||||
|
--f7-subnavbar-height: 56px;
|
||||||
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
--brand-cell: #34C759;
|
--brand-cell: #34C759;
|
||||||
--brand-slide: #FE8C33;
|
--brand-slide: #FE8C33;
|
||||||
--brand-form: #FE8C33;
|
--brand-form: #FE8C33;
|
||||||
|
--brand-visio: #d57bed;
|
||||||
--brand-primary: #3E9CF0;
|
--brand-primary: #3E9CF0;
|
||||||
--brand-secondary: #FFAF49;
|
--brand-secondary: #FFAF49;
|
||||||
--brand-text-on-brand: #000;
|
--brand-text-on-brand: #000;
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
--brand-cell: #40865C;
|
--brand-cell: #40865C;
|
||||||
--brand-slide: #BE664F;
|
--brand-slide: #BE664F;
|
||||||
--brand-form: #AA5252;
|
--brand-form: #AA5252;
|
||||||
|
--brand-visio: #444796;
|
||||||
--brand-primary: #3880BE;
|
--brand-primary: #3880BE;
|
||||||
--brand-secondary: #ED7309;
|
--brand-secondary: #ED7309;
|
||||||
--brand-text-on-brand: #FFF;
|
--brand-text-on-brand: #FFF;
|
||||||
@ -84,6 +85,7 @@
|
|||||||
@brand-cell: var(--brand-cell);
|
@brand-cell: var(--brand-cell);
|
||||||
@brand-slide: var(--brand-slide);
|
@brand-slide: var(--brand-slide);
|
||||||
@brand-form: var(--brand-form);
|
@brand-form: var(--brand-form);
|
||||||
|
@brand-visio: var(--brand-visio);
|
||||||
@brand-primary: var(--brand-primary);
|
@brand-primary: var(--brand-primary);
|
||||||
@brand-secondary: var(--brand-secondary);
|
@brand-secondary: var(--brand-secondary);
|
||||||
@brand-text-on-brand: var(--brand-text-on-brand);
|
@brand-text-on-brand: var(--brand-text-on-brand);
|
||||||
|
|||||||
269
apps/visioeditor/mobile/locale/en.json
Normal file
269
apps/visioeditor/mobile/locale/en.json
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
{
|
||||||
|
"About": {
|
||||||
|
"textAbout": "About",
|
||||||
|
"textAddress": "Address",
|
||||||
|
"textBack": "Back",
|
||||||
|
"textEditor": "Visio Editor",
|
||||||
|
"textEmail": "Email",
|
||||||
|
"textPoweredBy": "Powered By",
|
||||||
|
"textTel": "Tel",
|
||||||
|
"textVersion": "Version"
|
||||||
|
},
|
||||||
|
"Common": {
|
||||||
|
"Collaboration": {
|
||||||
|
"notcriticalErrorTitle": "Warning",
|
||||||
|
"textAddComment": "Add Comment",
|
||||||
|
"textAddReply": "Add Reply",
|
||||||
|
"textBack": "Back",
|
||||||
|
"textCancel": "Cancel",
|
||||||
|
"textCollaboration": "Collaboration",
|
||||||
|
"textComments": "Comments",
|
||||||
|
"textDeleteComment": "Delete Comment",
|
||||||
|
"textDeleteReply": "Delete Reply",
|
||||||
|
"textDone": "Done",
|
||||||
|
"textEdit": "Edit",
|
||||||
|
"textEditComment": "Edit Comment",
|
||||||
|
"textEditReply": "Edit Reply",
|
||||||
|
"textEditUser": "Users who are editing the file:",
|
||||||
|
"textMessageDeleteComment": "Do you really want to delete this comment?",
|
||||||
|
"textMessageDeleteReply": "Do you really want to delete this reply?",
|
||||||
|
"textNoComments": "No Comments",
|
||||||
|
"textOk": "Ok",
|
||||||
|
"textReopen": "Reopen",
|
||||||
|
"textResolve": "Resolve",
|
||||||
|
"textSharingSettings": "Sharing Settings",
|
||||||
|
"textTryUndoRedo": "The Undo/Redo functions are disabled for the Fast co-editing mode.",
|
||||||
|
"textUsers": "Users"
|
||||||
|
},
|
||||||
|
"Themes": {
|
||||||
|
"dark": "Dark",
|
||||||
|
"light": "Light",
|
||||||
|
"system": "Same as system",
|
||||||
|
"textTheme": "Theme"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ContextMenu": {
|
||||||
|
"errorCopyCutPaste": "Copy, cut and paste actions using the context menu will be performed within the current file only.",
|
||||||
|
"menuAddComment": "Add comment",
|
||||||
|
"menuCancel": "Cancel",
|
||||||
|
"menuViewComment": "View Comment",
|
||||||
|
"textCopyCutPasteActions": "Copy, Cut and Paste Actions",
|
||||||
|
"textDoNotShowAgain": "Don't show again",
|
||||||
|
"textOk": "Ok",
|
||||||
|
"txtWarnUrl": "Clicking this link can be harmful to your device and data.<br>Are you sure you want to continue?"
|
||||||
|
},
|
||||||
|
"Controller": {
|
||||||
|
"Main": {
|
||||||
|
"advDRMOptions": "Protected File",
|
||||||
|
"advDRMPassword": "Password",
|
||||||
|
"closeButtonText": "Close File",
|
||||||
|
"criticalErrorTitle": "Error",
|
||||||
|
"errorAccessDeny": "You are trying to perform an action you do not have rights for.<br>Please, contact your admin.",
|
||||||
|
"errorOpensource": "Using the free Community version, you can open documents for viewing only. To access mobile web editors, a commercial license is required.",
|
||||||
|
"errorProcessSaveResult": "Saving failed.",
|
||||||
|
"errorServerVersion": "The editor version has been updated. The page will be reloaded to apply the changes.",
|
||||||
|
"errorUpdateVersion": "The file version has been changed. The page will be reloaded.",
|
||||||
|
"leavePageText": "You have unsaved changes in this document. Click 'Stay on this Page' to wait for autosave. Click 'Leave this Page' to discard all the unsaved changes.",
|
||||||
|
"notcriticalErrorTitle": "Warning",
|
||||||
|
"SDK": {
|
||||||
|
},
|
||||||
|
"textAnonymous": "Anonymous",
|
||||||
|
"textBuyNow": "Visit website",
|
||||||
|
"textClose": "Close",
|
||||||
|
"textContactUs": "Contact sales",
|
||||||
|
"textCustomLoader": "Sorry, you are not entitled to change the loader. Please, contact our sales department to get a quote.",
|
||||||
|
"textGuest": "Guest",
|
||||||
|
"textHasMacros": "The file contains automatic macros.<br>Do you want to run macros?",
|
||||||
|
"textNo": "No",
|
||||||
|
"textNoLicenseTitle": "License limit reached",
|
||||||
|
"textNoMatches": "No Matches",
|
||||||
|
"textOk": "Ok",
|
||||||
|
"textOpenFile": "Enter a password to open the file",
|
||||||
|
"textPaidFeature": "Paid feature",
|
||||||
|
"textRemember": "Remember my choice",
|
||||||
|
"textReplaceSkipped": "The replacement has been made. {0} occurrences were skipped.",
|
||||||
|
"textReplaceSuccess": "The search has been done. Occurrences replaced: {0}",
|
||||||
|
"textRequestMacros": "A macro makes a request to URL. Do you want to allow the request to the %1?",
|
||||||
|
"textYes": "Yes",
|
||||||
|
"titleLicenseExp": "License expired",
|
||||||
|
"titleLicenseNotActive": "License not active",
|
||||||
|
"titleServerVersion": "Editor updated",
|
||||||
|
"titleUpdateVersion": "Version changed",
|
||||||
|
"txtIncorrectPwd": "Password is incorrect",
|
||||||
|
"txtProtected": "Once you enter the password and open the file, the current password to the file will be reset",
|
||||||
|
"warnLicenseAnonymous": "Access denied for anonymous users.<br>This document will be opened for viewing only.",
|
||||||
|
"warnLicenseBefore": "License not active.<br>Please contact your administrator.",
|
||||||
|
"warnLicenseExceeded": "You've reached the limit for simultaneous connections to %1 editors. This document will be opened for viewing only. Contact your administrator to learn more.",
|
||||||
|
"warnLicenseExp": "Your license has expired. Please, update your license and refresh the page.",
|
||||||
|
"warnLicenseLimitedNoAccess": "License expired. You have no access to document editing functionality. Please, contact your administrator.",
|
||||||
|
"warnLicenseLimitedRenewed": "License needs to be renewed. You have limited access to document editing functionality.<br>Please contact your administrator to get full access",
|
||||||
|
"warnLicenseUsersExceeded": "You've reached the user limit for %1 editors. Contact your administrator to learn more.",
|
||||||
|
"warnNoLicense": "You've reached the limit for simultaneous connections to %1 editors. This document will be opened for viewing only. Contact %1 sales team for personal upgrade terms.",
|
||||||
|
"warnNoLicenseUsers": "You've reached the user limit for %1 editors. Contact %1 sales team for personal upgrade terms.",
|
||||||
|
"warnProcessRightsChange": "You don't have permission to edit the file."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Error": {
|
||||||
|
"convertationTimeoutText": "Conversion timeout exceeded.",
|
||||||
|
"criticalErrorExtText": "Press 'OK' to go back to the document list.",
|
||||||
|
"criticalErrorTitle": "Error",
|
||||||
|
"downloadErrorText": "Download failed.",
|
||||||
|
"errorAccessDeny": "You are trying to perform an action you do not have rights for.<br>Please contact your admin.",
|
||||||
|
"errorBadImageUrl": "Image URL is incorrect",
|
||||||
|
"errorComboSeries": "To create a combination chart, select at least two series of data.",
|
||||||
|
"errorConnectToServer": "Can't save this doc. Check your connection settings or contact your admin.<br>When you click the 'OK' button, you will be prompted to download the document.",
|
||||||
|
"errorDatabaseConnection": "External error.<br>Database connection error. Please, contact support.",
|
||||||
|
"errorDataEncrypted": "Encrypted changes have been received, they cannot be deciphered.",
|
||||||
|
"errorDataRange": "Incorrect data range.",
|
||||||
|
"errorDefaultMessage": "Error code: %1",
|
||||||
|
"errorDirectUrl": "Please verify the link to the document.<br>This link must be a direct link to the file for downloading.",
|
||||||
|
"errorEditingDownloadas": "An error occurred during the work with the document.<br>Use the 'Download' option to save the file backup copy locally.",
|
||||||
|
"errorEmailClient": "No email client could be found",
|
||||||
|
"errorFilePassProtect": "The file is password protected and could not be opened.",
|
||||||
|
"errorFileSizeExceed": "The file size exceeds your server limitation.<br>Please, contact your admin.",
|
||||||
|
"errorForceSave": "An error occurred while saving the file. Please use the 'Download as' option to save the file to your computer hard drive or try again later.",
|
||||||
|
"errorInconsistentExt": "An error has occurred while opening the file.<br>The file content does not match the file extension.",
|
||||||
|
"errorInconsistentExtDocx": "An error has occurred while opening the file.<br>The file content corresponds to text documents (e.g. docx), but the file has the inconsistent extension: %1.",
|
||||||
|
"errorInconsistentExtPdf": "An error has occurred while opening the file.<br>The file content corresponds to one of the following formats: pdf/djvu/xps/oxps, but the file has the inconsistent extension: %1.",
|
||||||
|
"errorInconsistentExtPptx": "An error has occurred while opening the file.<br>The file content corresponds to presentations (e.g. pptx), but the file has the inconsistent extension: %1.",
|
||||||
|
"errorInconsistentExtXlsx": "An error has occurred while opening the file.<br>The file content corresponds to spreadsheets (e.g. xlsx), but the file has the inconsistent extension: %1.",
|
||||||
|
"errorKeyEncrypt": "Unknown key descriptor",
|
||||||
|
"errorKeyExpire": "Key descriptor expired",
|
||||||
|
"errorLoadingFont": "Fonts are not loaded.<br>Please contact your Document Server administrator.",
|
||||||
|
"errorSaveWatermark": "This file contains a watermark image linked to another domain.<br>To make it visible in PDF, update the watermark image so it links from the same domain as your document, or upload it from your computer.",
|
||||||
|
"errorSessionAbsolute": "The document editing session has expired. Please, reload the page.",
|
||||||
|
"errorSessionIdle": "The document has not been edited for quite a long time. Please, reload the page.",
|
||||||
|
"errorSessionToken": "The connection to the server has been interrupted. Please, reload the page.",
|
||||||
|
"errorSetPassword": "Password could not be set.",
|
||||||
|
"errorStockChart": "Incorrect row order. To build a stock chart, place the data on the sheet in the following order:<br> opening price, max price, min price, closing price.",
|
||||||
|
"errorToken": "The document security token is not correctly formed.<br>Please contact your Document Server administrator.",
|
||||||
|
"errorTokenExpire": "The document security token has expired.<br>Please contact your Document Server administrator.",
|
||||||
|
"errorUpdateVersionOnDisconnect": "Connection has been restored, and the file version has been changed.<br>Before you can continue working, download the file or copy its content to make sure nothing is lost, and then reload this page.",
|
||||||
|
"errorUserDrop": "The file cannot be accessed right now.",
|
||||||
|
"errorUsersExceed": "The number of users allowed by the pricing plan was exceeded",
|
||||||
|
"errorViewerDisconnect": "Connection is lost. You can still view the document,<br>but you won't be able to download or print it until the connection is restored and the page is reloaded.",
|
||||||
|
"notcriticalErrorTitle": "Warning",
|
||||||
|
"openErrorText": "An error has occurred while opening the file",
|
||||||
|
"saveErrorText": "An error has occurred while saving the file",
|
||||||
|
"scriptLoadError": "The connection is too slow, some of the components could not be loaded. Please, reload the page.",
|
||||||
|
"splitDividerErrorText": "The number of rows must be a divisor of %1",
|
||||||
|
"splitMaxColsErrorText": "The number of columns must be less than %1",
|
||||||
|
"splitMaxRowsErrorText": "The number of rows must be less than %1",
|
||||||
|
"textOk": "OK",
|
||||||
|
"unknownErrorText": "Unknown error.",
|
||||||
|
"uploadImageExtMessage": "Unknown image format.",
|
||||||
|
"uploadImageFileCountMessage": "No images uploaded.",
|
||||||
|
"uploadImageSizeMessage": "The image is too big. The maximum size is 25 MB."
|
||||||
|
},
|
||||||
|
"LongActions": {
|
||||||
|
"applyChangesTextText": "Loading data...",
|
||||||
|
"applyChangesTitleText": "Loading Data",
|
||||||
|
"confirmMaxChangesSize": "The size of actions exceeds the limitation set for your server.<br>Press \"Undo\" to cancel your last action or press \"Continue\" to keep action locally (you need to download the file or copy its content to make sure nothing is lost).",
|
||||||
|
"downloadTextText": "Downloading document...",
|
||||||
|
"downloadTitleText": "Downloading Document",
|
||||||
|
"loadFontsTextText": "Loading data...",
|
||||||
|
"loadFontsTitleText": "Loading Data",
|
||||||
|
"loadFontTextText": "Loading data...",
|
||||||
|
"loadFontTitleText": "Loading Data",
|
||||||
|
"loadImagesTextText": "Loading images...",
|
||||||
|
"loadImagesTitleText": "Loading Images",
|
||||||
|
"loadImageTextText": "Loading image...",
|
||||||
|
"loadImageTitleText": "Loading Image",
|
||||||
|
"loadingDocumentTextText": "Loading document...",
|
||||||
|
"loadingDocumentTitleText": "Loading",
|
||||||
|
"loadThemeTextText": "Loading theme...",
|
||||||
|
"loadThemeTitleText": "Loading Theme",
|
||||||
|
"openTextText": "Opening document...",
|
||||||
|
"openTitleText": "Opening Document",
|
||||||
|
"printTextText": "Printing document...",
|
||||||
|
"printTitleText": "Printing Document",
|
||||||
|
"savePreparingText": "Preparing to save",
|
||||||
|
"savePreparingTitle": "Preparing to save. Please wait...",
|
||||||
|
"saveTextText": "Saving document...",
|
||||||
|
"saveTitleText": "Saving Document",
|
||||||
|
"textContinue": "Continue",
|
||||||
|
"textLoadingDocument": "Loading",
|
||||||
|
"textUndo": "Undo",
|
||||||
|
"txtEditingMode": "Set editing mode...",
|
||||||
|
"uploadImageTextText": "Uploading image...",
|
||||||
|
"uploadImageTitleText": "Uploading Image",
|
||||||
|
"waitText": "Please, wait..."
|
||||||
|
},
|
||||||
|
"Toolbar": {
|
||||||
|
"dlgLeaveMsgText": "You have unsaved changes in this document. Click 'Stay on this Page' to wait for autosave. Click 'Leave this Page' to discard all the unsaved changes.",
|
||||||
|
"dlgLeaveTitleText": "You leave the application",
|
||||||
|
"leaveButtonText": "Leave this page",
|
||||||
|
"stayButtonText": "Stay on this Page",
|
||||||
|
"textCloseHistory": "Close History",
|
||||||
|
"textEnterNewFileName": "Enter a new file name",
|
||||||
|
"textRenameFile": "Rename File"
|
||||||
|
},
|
||||||
|
"View": {
|
||||||
|
"Settings": {
|
||||||
|
"notcriticalErrorTitle": "Warning",
|
||||||
|
"textAbout": "About",
|
||||||
|
"textAddress": "address:",
|
||||||
|
"textApplication": "Application",
|
||||||
|
"textApplicationSettings": "Application Settings",
|
||||||
|
"textAuthor": "Author",
|
||||||
|
"textBack": "Back",
|
||||||
|
"textCaseSensitive": "Case Sensitive",
|
||||||
|
"textCentimeter": "Centimeter",
|
||||||
|
"textClose": "Close",
|
||||||
|
"textCollaboration": "Collaboration",
|
||||||
|
"textComment": "Comment",
|
||||||
|
"textCreated": "Created",
|
||||||
|
"textDark": "Dark",
|
||||||
|
"textDarkTheme": "Dark Theme",
|
||||||
|
"textDisableAll": "Disable All",
|
||||||
|
"textDisableAllMacrosWithNotification": "Disable all macros with notification",
|
||||||
|
"textDisableAllMacrosWithoutNotification": "Disable all macros without notification",
|
||||||
|
"textDone": "Done",
|
||||||
|
"textDownload": "Download",
|
||||||
|
"textDownloadAs": "Download As...",
|
||||||
|
"textEmail": "email:",
|
||||||
|
"textEnableAll": "Enable All",
|
||||||
|
"textEnableAllMacrosWithoutNotification": "Enable all macros without notification",
|
||||||
|
"textFeedback": "Feedback & Support",
|
||||||
|
"textFind": "Find",
|
||||||
|
"textFindAndReplace": "Find and Replace",
|
||||||
|
"textFindAndReplaceAll": "Find and Replace All",
|
||||||
|
"textHelp": "Help",
|
||||||
|
"textHighlight": "Highlight Results",
|
||||||
|
"textInch": "Inch",
|
||||||
|
"textLastModified": "Last Modified",
|
||||||
|
"textLastModifiedBy": "Last Modified By",
|
||||||
|
"textLight": "Light",
|
||||||
|
"textLoading": "Loading...",
|
||||||
|
"textLocation": "Location",
|
||||||
|
"textMacrosSettings": "Macros Settings",
|
||||||
|
"textNoMatches": "No Matches",
|
||||||
|
"textOk": "Ok",
|
||||||
|
"textOwner": "Owner",
|
||||||
|
"textPoint": "Point",
|
||||||
|
"textPoweredBy": "Powered By",
|
||||||
|
"textVisioInfo": "Visio Info",
|
||||||
|
"textVisioSettings": "Visio Settings",
|
||||||
|
"textVisioTitle": "Visio Title",
|
||||||
|
"textPrint": "Print",
|
||||||
|
"textReplace": "Replace",
|
||||||
|
"textReplaceAll": "Replace All",
|
||||||
|
"textRestartApplication": "Please restart the application for the changes to take effect",
|
||||||
|
"textSameAsSystem": "Same As System",
|
||||||
|
"textSearch": "Find",
|
||||||
|
"textSettings": "Settings",
|
||||||
|
"textShowNotification": "Show Notification",
|
||||||
|
"textSubject": "Subject",
|
||||||
|
"textTel": "tel:",
|
||||||
|
"textTheme": "Theme",
|
||||||
|
"textTitle": "Title",
|
||||||
|
"textUnitOfMeasurement": "Unit Of Measurement",
|
||||||
|
"textUploaded": "Uploaded",
|
||||||
|
"textVersion": "Version"
|
||||||
|
},
|
||||||
|
"Edit": {
|
||||||
|
"textCancel": "Cancel",
|
||||||
|
"textOk": "Ok"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
46
apps/visioeditor/mobile/src/app.js
Normal file
46
apps/visioeditor/mobile/src/app.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// Import React and ReactDOM
|
||||||
|
import React, { Suspense } from 'react';
|
||||||
|
import { createRoot } from 'react-dom/client';
|
||||||
|
|
||||||
|
// Import Framework7
|
||||||
|
import Framework7 from 'framework7/lite-bundle';
|
||||||
|
import { Dom7 } from 'framework7/lite-bundle';
|
||||||
|
window.$$ = Dom7;
|
||||||
|
|
||||||
|
// Import Framework7-React Plugin
|
||||||
|
import Framework7React from 'framework7-react';
|
||||||
|
|
||||||
|
import jQuery from 'jquery';
|
||||||
|
window.jQuery = jQuery;
|
||||||
|
window.$ = jQuery;
|
||||||
|
|
||||||
|
// Import Framework7 or Framework7-RTL Styles
|
||||||
|
|
||||||
|
// Import App Custom Styles
|
||||||
|
import('./less/app.less');
|
||||||
|
|
||||||
|
// Import App Component
|
||||||
|
import App from './page/app.jsx';
|
||||||
|
import { I18nextProvider } from 'react-i18next';
|
||||||
|
import i18n from './lib/i18n.js';
|
||||||
|
|
||||||
|
import { Provider } from 'mobx-react';
|
||||||
|
import { stores } from './store/mainStore.js';
|
||||||
|
// import { LocalStorage } from '../../../common/mobile/utils/LocalStorage';
|
||||||
|
|
||||||
|
const container = document.getElementById('app');
|
||||||
|
const root = createRoot(container);
|
||||||
|
|
||||||
|
// Init F7 React Plugin
|
||||||
|
Framework7.use(Framework7React);
|
||||||
|
|
||||||
|
// Mount React App
|
||||||
|
root.render(
|
||||||
|
<I18nextProvider i18n={i18n}>
|
||||||
|
<Provider {...stores}>
|
||||||
|
{/*<Suspense fallback="loading...">*/}
|
||||||
|
<App />
|
||||||
|
{/*</Suspense>*/}
|
||||||
|
</Provider>
|
||||||
|
</I18nextProvider>
|
||||||
|
);
|
||||||
142
apps/visioeditor/mobile/src/controller/ContextMenu.jsx
Normal file
142
apps/visioeditor/mobile/src/controller/ContextMenu.jsx
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
import React, { useContext } from 'react';
|
||||||
|
import { f7 } from 'framework7-react';
|
||||||
|
import { inject, observer } from "mobx-react";
|
||||||
|
import { withTranslation} from 'react-i18next';
|
||||||
|
import { LocalStorage } from '../../../../common/mobile/utils/LocalStorage.mjs';
|
||||||
|
|
||||||
|
import ContextMenuController from '../../../../common/mobile/lib/controller/ContextMenu';
|
||||||
|
import { idContextMenuElement } from '../../../../common/mobile/lib/view/ContextMenu';
|
||||||
|
// import { Device } from '../../../../common/mobile/utils/device';
|
||||||
|
import EditorUIController from '../lib/patch';
|
||||||
|
|
||||||
|
@inject(stores => ({
|
||||||
|
users: stores.users,
|
||||||
|
isDisconnected: stores.users.isDisconnected
|
||||||
|
}))
|
||||||
|
class ContextMenu extends ContextMenuController {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
// console.log('context menu controller created');
|
||||||
|
this.getUserName = this.getUserName.bind(this);
|
||||||
|
this.isUserVisible = this.isUserVisible.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
static closeContextMenu() {
|
||||||
|
f7.popover.close(idContextMenuElement, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUserName(id) {
|
||||||
|
const user = this.props.users.searchUserByCurrentId(id);
|
||||||
|
return AscCommon.UserInfoParser.getParsedName(user.asc_getUserName());
|
||||||
|
}
|
||||||
|
|
||||||
|
isUserVisible(id) {
|
||||||
|
const user = this.props.users.searchUserByCurrentId(id);
|
||||||
|
return user ? (user.asc_getIdOriginal()===this.props.users.currentUser.asc_getIdOriginal() || AscCommon.UserInfoParser.isUserVisible(user.asc_getUserName())) : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
super.componentWillUnmount();
|
||||||
|
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
if ( api ) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// onMenuClosed() {
|
||||||
|
// super.onMenuClosed();
|
||||||
|
// }
|
||||||
|
|
||||||
|
onMenuItemClick(action) {
|
||||||
|
super.onMenuItemClick(action);
|
||||||
|
|
||||||
|
if ( EditorUIController.ContextMenu && EditorUIController.ContextMenu.handleMenuItemClick(this, action) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case 'openlink':
|
||||||
|
const stack = Common.EditorApi.get().getSelectedElements();
|
||||||
|
let value;
|
||||||
|
stack.forEach((item) => {
|
||||||
|
if (item.get_ObjectType() == Asc.c_oAscTypeSelectElement.Hyperlink) {
|
||||||
|
value = item.get_ObjectValue().get_Value();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
value && this.openLink(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
openLink(url) {
|
||||||
|
if (url) {
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
const type = api.asc_getUrlType(url);
|
||||||
|
if (type===AscCommon.c_oAscUrlType.Http || type===AscCommon.c_oAscUrlType.Email) {
|
||||||
|
const newDocumentPage = window.open(url, '_blank');
|
||||||
|
if (newDocumentPage) {
|
||||||
|
newDocumentPage.focus();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const { t } = this.props;
|
||||||
|
const _t = t("ContextMenu", { returnObjects: true });
|
||||||
|
f7.dialog.create({
|
||||||
|
title: t('View.Settings', {returnObjects: true}).notcriticalErrorTitle,
|
||||||
|
text : _t.txtWarnUrl,
|
||||||
|
buttons: [{
|
||||||
|
text: t('View.Settings', {returnObjects: true}).textOk,
|
||||||
|
bold: true,
|
||||||
|
onClick: () => {
|
||||||
|
const newDocumentPage = window.open(url, '_blank');
|
||||||
|
if (newDocumentPage) {
|
||||||
|
newDocumentPage.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ text: _t.menuCancel }]
|
||||||
|
}).open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onDocumentReady() {
|
||||||
|
super.onDocumentReady();
|
||||||
|
}
|
||||||
|
|
||||||
|
initMenuItems() {
|
||||||
|
if ( !Common.EditorApi ) return [];
|
||||||
|
|
||||||
|
const { t } = this.props;
|
||||||
|
const _t = t("ContextMenu", { returnObjects: true });
|
||||||
|
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
const stack = api.getSelectedElements();
|
||||||
|
|
||||||
|
let itemsText = [];
|
||||||
|
let isLink = false;
|
||||||
|
|
||||||
|
stack.forEach(item => {
|
||||||
|
const objectType = item.get_ObjectType();
|
||||||
|
if (objectType == Asc.c_oAscTypeSelectElement.Hyperlink) {
|
||||||
|
isLink = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isLink) {
|
||||||
|
itemsText.push({
|
||||||
|
caption: _t.menuOpenLink,
|
||||||
|
event: 'openlink'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemsText;
|
||||||
|
}
|
||||||
|
|
||||||
|
initExtraItems () {
|
||||||
|
return (this.extraItems && this.extraItems.length > 0 ? this.extraItems : []);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const _ContextMenu = withTranslation()(ContextMenu);
|
||||||
|
_ContextMenu.closeContextMenu = ContextMenu.closeContextMenu;
|
||||||
|
export { _ContextMenu as default };
|
||||||
259
apps/visioeditor/mobile/src/controller/Error.jsx
Normal file
259
apps/visioeditor/mobile/src/controller/Error.jsx
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
import React, { useEffect } from 'react';
|
||||||
|
import { inject } from 'mobx-react';
|
||||||
|
import { f7 } from 'framework7-react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
const ErrorController = inject('storeAppOptions','storeVisioInfo')(({storeAppOptions, storeVisioInfo, LoadingDocument}) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const _t = t("Error", { returnObjects: true });
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const on_engine_created = k => { k.asc_registerCallback('asc_onError', onError); };
|
||||||
|
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
if ( !api ) Common.Notifications.on('engineCreated', on_engine_created);
|
||||||
|
else on_engine_created(api);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
if ( api ) api.asc_unregisterCallback('asc_onError', onError);
|
||||||
|
|
||||||
|
Common.Notifications.off('engineCreated', on_engine_created);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const onError = (id, level, errData) => {
|
||||||
|
if (id === Asc.c_oAscError.ID.LoadingScriptError) {
|
||||||
|
f7.notification.create({
|
||||||
|
title: _t.criticalErrorTitle,
|
||||||
|
text: _t.scriptLoadError,
|
||||||
|
closeButton: true
|
||||||
|
}).open();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Common.Notifications.trigger('preloader:close');
|
||||||
|
Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], LoadingDocument,true);
|
||||||
|
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
closable: false
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (id) {
|
||||||
|
case Asc.c_oAscError.ID.Unknown:
|
||||||
|
config.msg = _t.unknownErrorText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.ConvertationTimeout:
|
||||||
|
config.msg = _t.convertationTimeoutText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.ConvertationOpenError:
|
||||||
|
config.msg = _t.openErrorText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.ConvertationSaveError:
|
||||||
|
config.msg = _t.saveErrorText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.DownloadError:
|
||||||
|
config.msg = _t.downloadErrorText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.UplImageSize:
|
||||||
|
config.msg = _t.uploadImageSizeMessage;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.UplImageExt:
|
||||||
|
config.msg = _t.uploadImageExtMessage;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.UplImageFileCount:
|
||||||
|
config.msg = _t.uploadImageFileCountMessage;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.SplitCellMaxRows:
|
||||||
|
config.msg = _t.splitMaxRowsErrorText.replace('%1', errData.get_Value());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.SplitCellMaxCols:
|
||||||
|
config.msg = _t.splitMaxColsErrorText.replace('%1', errData.get_Value());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.SplitCellRowsDivider:
|
||||||
|
config.msg = _t.splitDividerErrorText.replace('%1', errData.get_Value());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.VKeyEncrypt:
|
||||||
|
config.msg = _t.errorToken;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.KeyExpire:
|
||||||
|
config.msg = _t.errorTokenExpire;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.UserCountExceed:
|
||||||
|
config.msg = _t.errorUsersExceed;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.CoAuthoringDisconnect:
|
||||||
|
config.msg = _t.errorViewerDisconnect;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.ConvertationPassword:
|
||||||
|
config.msg = _t.errorFilePassProtect;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.StockChartError:
|
||||||
|
config.msg = _t.errorStockChart;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.Database:
|
||||||
|
config.msg = _t.errorDatabaseConnection;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.UserDrop:
|
||||||
|
const lostEditingRights = storeAppOptions.lostEditingRights;
|
||||||
|
if (lostEditingRights) {
|
||||||
|
storeAppOptions.changeEditingRights(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
storeAppOptions.changeEditingRights(true);
|
||||||
|
config.msg = _t.errorUserDrop;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.Warning:
|
||||||
|
config.msg = _t.errorConnectToServer;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.UplImageUrl:
|
||||||
|
config.msg = _t.errorBadImageUrl;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.SessionAbsolute:
|
||||||
|
config.msg = _t.errorSessionAbsolute;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.SessionIdle:
|
||||||
|
config.msg = _t.errorSessionIdle;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.SessionToken:
|
||||||
|
config.msg = _t.errorSessionToken;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.DataEncrypted:
|
||||||
|
config.msg = _t.errorDataEncrypted;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.AccessDeny:
|
||||||
|
config.msg = _t.errorAccessDeny;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.ForceSaveButton:
|
||||||
|
case Asc.c_oAscError.ID.ForceSaveTimeout:
|
||||||
|
config.msg = t('Error.errorForceSave');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.EditingError:
|
||||||
|
config.msg = _t.errorEditingDownloadas;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.MailToClientMissing:
|
||||||
|
config.msg = t('Error.errorEmailClient');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.ConvertationOpenLimitError:
|
||||||
|
config.msg = _t.errorFileSizeExceed;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.UpdateVersion:
|
||||||
|
config.msg = _t.errorUpdateVersionOnDisconnect;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.Password:
|
||||||
|
config.msg = t('Error.errorSetPassword');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.LoadingFontError:
|
||||||
|
config.msg = _t.errorLoadingFont;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.DirectUrl:
|
||||||
|
config.msg = _t.errorDirectUrl;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.ConvertationOpenFormat:
|
||||||
|
let docExt = storeVisioInfo.dataDoc ? storeVisioInfo.dataDoc.fileType || '' : '';
|
||||||
|
if (errData === 'pdf')
|
||||||
|
config.msg = _t.errorInconsistentExtPdf.replace('%1', docExt);
|
||||||
|
else if (errData === 'docx')
|
||||||
|
config.msg = _t.errorInconsistentExtDocx.replace('%1', docExt);
|
||||||
|
else if (errData === 'xlsx')
|
||||||
|
config.msg = _t.errorInconsistentExtXlsx.replace('%1', docExt);
|
||||||
|
else if (errData === 'pptx')
|
||||||
|
config.msg = _t.errorInconsistentExtPptx.replace('%1', docExt);
|
||||||
|
else
|
||||||
|
config.msg = _t.errorInconsistentExt;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscError.ID.CannotSaveWatermark:
|
||||||
|
config.msg = t('Error.errorSaveWatermark');
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
config.msg = _t.errorDefaultMessage.replace('%1', id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (level === Asc.c_oAscError.Level.Critical) {
|
||||||
|
|
||||||
|
// report only critical errors
|
||||||
|
Common.Gateway.reportError(id, config.msg);
|
||||||
|
|
||||||
|
config.title = _t.criticalErrorTitle;
|
||||||
|
|
||||||
|
if (storeAppOptions.canBackToFolder && !storeAppOptions.isDesktopApp) {
|
||||||
|
config.msg += '</br></br>' + _t.criticalErrorExtText;
|
||||||
|
config.callback = function() {
|
||||||
|
Common.Notifications.trigger('goback', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (id === Asc.c_oAscError.ID.DataEncrypted) {
|
||||||
|
api.asc_coAuthoringDisconnect();
|
||||||
|
Common.Notifications.trigger('api:disconnect');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Common.Gateway.reportWarning(id, config.msg);
|
||||||
|
|
||||||
|
config.title = _t.notcriticalErrorTitle;
|
||||||
|
config.callback = (btn) => {
|
||||||
|
if (id === Asc.c_oAscError.ID.Warning && btn === 'ok' && (storeAppOptions.canDownload || storeAppOptions.canDownloadOrigin)) {
|
||||||
|
api.asc_DownloadOrigin();
|
||||||
|
}
|
||||||
|
storeAppOptions.changeEditingRights(false);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
f7.dialog.create({
|
||||||
|
cssClass: 'error-dialog',
|
||||||
|
title : config.title,
|
||||||
|
text : config.msg,
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
text: _t.textOk,
|
||||||
|
onClick: config.callback
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}).open();
|
||||||
|
|
||||||
|
Common.component.Analytics.trackEvent('Internal Error', id.toString());
|
||||||
|
};
|
||||||
|
|
||||||
|
return null
|
||||||
|
});
|
||||||
|
|
||||||
|
export default ErrorController;
|
||||||
217
apps/visioeditor/mobile/src/controller/LongActions.jsx
Normal file
217
apps/visioeditor/mobile/src/controller/LongActions.jsx
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
import React, { useEffect } from 'react';
|
||||||
|
import { f7 } from 'framework7-react';
|
||||||
|
import { inject } from 'mobx-react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import IrregularStack from "../../../../common/mobile/utils/IrregularStack";
|
||||||
|
|
||||||
|
const LongActionsController = inject('storeAppOptions')(({storeAppOptions}) => {
|
||||||
|
const {t} = useTranslation();
|
||||||
|
const _t = t("LongActions", {returnObjects: true});
|
||||||
|
|
||||||
|
const ApplyEditRights = -255;
|
||||||
|
const LoadingDocument = -256;
|
||||||
|
|
||||||
|
const stackLongActions = new IrregularStack({
|
||||||
|
strongCompare : function(obj1, obj2){return obj1.id === obj2.id && obj1.type === obj2.type;},
|
||||||
|
weakCompare : function(obj1, obj2){return obj1.type === obj2.type;}
|
||||||
|
});
|
||||||
|
|
||||||
|
let loadMask = null;
|
||||||
|
|
||||||
|
const closePreloader = () => {
|
||||||
|
if (loadMask && loadMask.el) {
|
||||||
|
f7.dialog.close(loadMask.el);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect( () => {
|
||||||
|
const on_engine_created = api => {
|
||||||
|
api.asc_registerCallback('asc_onStartAction', onLongActionBegin);
|
||||||
|
api.asc_registerCallback('asc_onEndAction', onLongActionEnd);
|
||||||
|
api.asc_registerCallback('asc_onOpenDocumentProgress', onOpenDocument);
|
||||||
|
api.asc_registerCallback('asc_onConfirmAction', onConfirmAction);
|
||||||
|
};
|
||||||
|
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
if(!api) Common.Notifications.on('engineCreated', on_engine_created);
|
||||||
|
else on_engine_created(api);
|
||||||
|
|
||||||
|
Common.Notifications.on('preloader:endAction', onLongActionEnd);
|
||||||
|
Common.Notifications.on('preloader:beginAction', onLongActionBegin);
|
||||||
|
Common.Notifications.on('preloader:close', closePreloader);
|
||||||
|
|
||||||
|
return (() => {
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
if ( api ) {
|
||||||
|
api.asc_unregisterCallback('asc_onStartAction', onLongActionBegin);
|
||||||
|
api.asc_unregisterCallback('asc_onEndAction', onLongActionEnd);
|
||||||
|
api.asc_unregisterCallback('asc_onOpenDocumentProgress', onOpenDocument);
|
||||||
|
api.asc_unregisterCallback('asc_onConfirmAction', onConfirmAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
Common.Notifications.off('engineCreated', on_engine_created);
|
||||||
|
Common.Notifications.off('preloader:endAction', onLongActionEnd);
|
||||||
|
Common.Notifications.off('preloader:beginAction', onLongActionBegin);
|
||||||
|
Common.Notifications.off('preloader:close', closePreloader);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const onLongActionBegin = (type, id) => {
|
||||||
|
const action = {id: id, type: type};
|
||||||
|
stackLongActions.push(action);
|
||||||
|
setLongActionView(action);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onLongActionEnd = (type, id, forceClose) => {
|
||||||
|
if (!stackLongActions.exist({id: id, type: type})) return;
|
||||||
|
|
||||||
|
let action = {id: id, type: type};
|
||||||
|
stackLongActions.pop(action);
|
||||||
|
|
||||||
|
//this.updateWindowTitle(true);
|
||||||
|
|
||||||
|
action = stackLongActions.get({type: Asc.c_oAscAsyncActionType.Information}) || stackLongActions.get({type: Asc.c_oAscAsyncActionType.BlockInteraction});
|
||||||
|
|
||||||
|
if (action && !forceClose) {
|
||||||
|
setLongActionView(action)
|
||||||
|
} else {
|
||||||
|
loadMask && loadMask.el && loadMask.el.classList.contains('modal-in') ?
|
||||||
|
f7.dialog.close(loadMask.el) :
|
||||||
|
f7.dialog.close($$('.dialog-preloader'));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const setLongActionView = (action) => {
|
||||||
|
let title = '';
|
||||||
|
// let text = '';
|
||||||
|
switch (action.id) {
|
||||||
|
case Asc.c_oAscAsyncAction['Open']:
|
||||||
|
title = _t.textLoadingDocument;
|
||||||
|
// title = _t.openTitleText;
|
||||||
|
// text = _t.openTextText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscAsyncAction['Save']:
|
||||||
|
title = _t.saveTitleText;
|
||||||
|
// text = _t.saveTextText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscAsyncAction['LoadDocumentFonts']:
|
||||||
|
if ( !storeAppOptions.isDocReady ) return;
|
||||||
|
title = _t.loadFontsTitleText;
|
||||||
|
// text = _t.loadFontsTextText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscAsyncAction['LoadDocumentImages']:
|
||||||
|
title = _t.loadImagesTitleText;
|
||||||
|
// text = _t.loadImagesTextText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscAsyncAction['LoadFont']:
|
||||||
|
title = _t.loadFontTitleText;
|
||||||
|
// text = _t.loadFontTextText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscAsyncAction['LoadImage']:
|
||||||
|
title = _t.loadImageTitleText;
|
||||||
|
// text = _t.loadImageTextText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscAsyncAction['DownloadAs']:
|
||||||
|
title = _t.downloadTitleText;
|
||||||
|
// text = _t.downloadTextText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscAsyncAction['Print']:
|
||||||
|
title = _t.printTitleText;
|
||||||
|
// text = _t.printTextText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscAsyncAction['UploadImage']:
|
||||||
|
title = _t.uploadImageTitleText;
|
||||||
|
// text = _t.uploadImageTextText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscAsyncAction['ApplyChanges']:
|
||||||
|
title = _t.applyChangesTitleText;
|
||||||
|
// text = _t.applyChangesTextText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscAsyncAction['PrepareToSave']:
|
||||||
|
title = _t.savePreparingText;
|
||||||
|
// text = _t.savePreparingTitle;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asc.c_oAscAsyncAction['Waiting']:
|
||||||
|
title = _t.waitText;
|
||||||
|
// text = _t.waitText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ApplyEditRights:
|
||||||
|
title = _t.txtEditingMode;
|
||||||
|
// text = _t.txtEditingMode;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LoadingDocument:
|
||||||
|
title = _t.loadingDocumentTitleText;
|
||||||
|
// text = _t.loadingDocumentTextText;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (typeof action.id == 'string'){
|
||||||
|
title = action.id;
|
||||||
|
// text = action.id;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.type === Asc.c_oAscAsyncActionType['BlockInteraction']) {
|
||||||
|
if (action.id === Asc.c_oAscAsyncAction['ApplyChanges'] || action.id === Asc.c_oAscAsyncAction['LoadDocumentFonts']) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loadMask && loadMask.el && loadMask.el.classList.contains('modal-in')) {
|
||||||
|
loadMask.el.getElementsByClassName('dialog-title')[0].innerHTML = title;
|
||||||
|
} else if ($$('.dialog-preloader').hasClass('modal-in')) {
|
||||||
|
$$('.dialog-preloader').find('dialog-title').text(title);
|
||||||
|
} else {
|
||||||
|
loadMask = f7.dialog.preloader(title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onConfirmAction = (id, apiCallback, data) => {
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
|
||||||
|
if (id === Asc.c_oAscConfirm.ConfirmMaxChangesSize) {
|
||||||
|
f7.dialog.create({
|
||||||
|
title: _t.notcriticalErrorTitle,
|
||||||
|
text: _t.confirmMaxChangesSize,
|
||||||
|
buttons: [
|
||||||
|
{text: _t.textUndo,
|
||||||
|
onClick: () => {
|
||||||
|
if (apiCallback) apiCallback(true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{text: _t.textContinue,
|
||||||
|
onClick: () => {
|
||||||
|
if (apiCallback) apiCallback(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}).open();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onOpenDocument = (progress) => {
|
||||||
|
if (loadMask && loadMask.el) {
|
||||||
|
const $title = loadMask.el.getElementsByClassName('dialog-title')[0];
|
||||||
|
const proc = (progress.asc_getCurrentFont() + progress.asc_getCurrentImage())/(progress.asc_getFontsCount() + progress.asc_getImagesCount());
|
||||||
|
|
||||||
|
$title.innerHTML = `${_t.textLoadingDocument}: ${Math.min(Math.round(proc * 100), 100)}%`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
export default LongActionsController;
|
||||||
780
apps/visioeditor/mobile/src/controller/Main.jsx
Normal file
780
apps/visioeditor/mobile/src/controller/Main.jsx
Normal file
@ -0,0 +1,780 @@
|
|||||||
|
|
||||||
|
import React, { Component, Fragment } from 'react'
|
||||||
|
import { inject } from "mobx-react";
|
||||||
|
import { f7 } from "framework7-react";
|
||||||
|
import { withTranslation } from 'react-i18next';
|
||||||
|
import CollaborationController from '../../../../common/mobile/lib/controller/collaboration/Collaboration.jsx';
|
||||||
|
import EditorUIController from '../lib/patch';
|
||||||
|
import ErrorController from "./Error";
|
||||||
|
import LongActionsController from "./LongActions";
|
||||||
|
import {LocalStorage} from "../../../../common/mobile/utils/LocalStorage.mjs";
|
||||||
|
import About from '../../../../common/mobile/lib/view/About';
|
||||||
|
import { Device } from '../../../../common/mobile/utils/device';
|
||||||
|
import { Themes } from '../../../../common/mobile/lib/controller/Themes.jsx';
|
||||||
|
import { processArrayScripts } from '../../../../common/mobile/utils/processArrayScripts.js';
|
||||||
|
import '../../../../common/main/lib/util/LanguageInfo.js'
|
||||||
|
|
||||||
|
@inject(
|
||||||
|
"users",
|
||||||
|
"storeAppOptions",
|
||||||
|
"storeVisioInfo",
|
||||||
|
"storeApplicationSettings",
|
||||||
|
"storeToolbarSettings"
|
||||||
|
)
|
||||||
|
class MainController extends Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props)
|
||||||
|
window.editorType = 've';
|
||||||
|
|
||||||
|
this.LoadingDocument = -256;
|
||||||
|
this.ApplyEditRights = -255;
|
||||||
|
this.fallbackSdkTranslations = {
|
||||||
|
};
|
||||||
|
|
||||||
|
this._state = {
|
||||||
|
licenseType: false,
|
||||||
|
isDocModified: false
|
||||||
|
};
|
||||||
|
|
||||||
|
this.defaultTitleText = __APP_TITLE_TEXT__;
|
||||||
|
this.stackMacrosRequests = [];
|
||||||
|
|
||||||
|
const { t } = this.props;
|
||||||
|
this._t = t('Controller.Main', {returnObjects:true});
|
||||||
|
}
|
||||||
|
|
||||||
|
initSdk () {
|
||||||
|
const on_script_load = () => {
|
||||||
|
!window.sdk_scripts && (window.sdk_scripts = ['../../../../sdkjs/common/AllFonts.js',
|
||||||
|
'../../../../sdkjs/draw/sdk-all-min.js']);
|
||||||
|
let dep_scripts = ['../../../vendor/xregexp/xregexp-all-min.js',
|
||||||
|
'../../../vendor/socketio/socket.io.min.js'];
|
||||||
|
dep_scripts.push(...window.sdk_scripts);
|
||||||
|
|
||||||
|
const promise_get_script = (scriptpath) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const script = document.createElement("script");
|
||||||
|
script.src = scriptpath;
|
||||||
|
script.onload = () => {
|
||||||
|
resolve('ok');
|
||||||
|
};
|
||||||
|
script.onerror = () => {
|
||||||
|
reject('error');
|
||||||
|
};
|
||||||
|
|
||||||
|
document.body.appendChild(script);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadConfig = data => {
|
||||||
|
const { t } = this.props;
|
||||||
|
const _t = t('Controller.Main', {returnObjects:true});
|
||||||
|
|
||||||
|
EditorUIController.isSupportEditFeature();
|
||||||
|
|
||||||
|
this.editorConfig = Object.assign({}, this.editorConfig, data.config);
|
||||||
|
|
||||||
|
this.props.storeAppOptions.setConfigOptions(this.editorConfig, _t);
|
||||||
|
|
||||||
|
this.editorConfig.lang && this.api.asc_setLocale(this.editorConfig.lang);
|
||||||
|
|
||||||
|
this.loadDefaultMetricSettings();
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadDocument = data => {
|
||||||
|
this.permissions = {};
|
||||||
|
this.document = data.doc;
|
||||||
|
|
||||||
|
let docInfo = {};
|
||||||
|
|
||||||
|
if (data.doc) {
|
||||||
|
this.permissions = Object.assign(this.permissions, data.doc.permissions);
|
||||||
|
|
||||||
|
const _options = Object.assign({}, data.doc.options, this.editorConfig.actionLink || {});
|
||||||
|
const _user = new Asc.asc_CUserInfo();
|
||||||
|
const _userOptions = this.props.storeAppOptions.user;
|
||||||
|
_user.put_Id(_userOptions.id);
|
||||||
|
_user.put_FullName(_userOptions.fullname);
|
||||||
|
_user.put_IsAnonymousUser(_userOptions.anonymous);
|
||||||
|
|
||||||
|
docInfo = new Asc.asc_CDocInfo();
|
||||||
|
docInfo.put_Id(data.doc.key);
|
||||||
|
docInfo.put_Url(data.doc.url);
|
||||||
|
docInfo.put_DirectUrl(data.doc.directUrl);
|
||||||
|
docInfo.put_Title(data.doc.title);
|
||||||
|
docInfo.put_Format(data.doc.fileType);
|
||||||
|
docInfo.put_VKey(data.doc.vkey);
|
||||||
|
docInfo.put_Options(_options);
|
||||||
|
docInfo.put_UserInfo(_user);
|
||||||
|
docInfo.put_CallbackUrl(this.editorConfig.callbackUrl);
|
||||||
|
docInfo.put_Token(data.doc.token);
|
||||||
|
docInfo.put_Permissions(data.doc.permissions);
|
||||||
|
docInfo.put_EncryptedInfo(this.editorConfig.encryptionKeys);
|
||||||
|
docInfo.put_Lang(this.editorConfig.lang);
|
||||||
|
docInfo.put_Mode(this.editorConfig.mode);
|
||||||
|
docInfo.put_Wopi(this.editorConfig.wopi);
|
||||||
|
this.editorConfig.shardkey && docInfo.put_Shardkey(this.editorConfig.shardkey);
|
||||||
|
|
||||||
|
// let coEditMode = !(this.editorConfig.coEditing && typeof this.editorConfig.coEditing == 'object') ? 'fast' : // fast by default
|
||||||
|
// this.editorConfig.mode === 'view' && this.editorConfig.coEditing.change!==false ? 'fast' : // if can change mode in viewer - set fast for using live viewer
|
||||||
|
// this.editorConfig.coEditing.mode || 'fast';
|
||||||
|
// docInfo.put_CoEditingMode(coEditMode);
|
||||||
|
var coEditMode = 'strict';
|
||||||
|
docInfo.put_CoEditingMode(coEditMode);
|
||||||
|
|
||||||
|
let enable = false;//!this.editorConfig.customization || (this.editorConfig.customization.macros !== false);
|
||||||
|
docInfo.asc_putIsEnabledMacroses(!!enable);
|
||||||
|
enable = false;//!this.editorConfig.customization || (this.editorConfig.customization.plugins !== false);
|
||||||
|
docInfo.asc_putIsEnabledPlugins(!!enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.api.asc_registerCallback('asc_onGetEditorPermissions', onEditorPermissions);
|
||||||
|
this.api.asc_registerCallback('asc_onLicenseChanged', this.onLicenseChanged.bind(this));
|
||||||
|
this.api.asc_setDocInfo(docInfo);
|
||||||
|
this.api.asc_getEditorPermissions(this.editorConfig.licenseUrl, this.editorConfig.customerId);
|
||||||
|
|
||||||
|
// Visio Info
|
||||||
|
|
||||||
|
const storeVisioInfo = this.props.storeVisioInfo;
|
||||||
|
|
||||||
|
storeVisioInfo.setDataDoc(this.document);
|
||||||
|
|
||||||
|
// Common.SharedSettings.set('document', data.doc);
|
||||||
|
|
||||||
|
if (data.doc) {
|
||||||
|
Common.Notifications.trigger('setdoctitle', data.doc.title);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onEditorPermissions = params => {
|
||||||
|
const licType = params.asc_getLicenseType();
|
||||||
|
const { t } = this.props;
|
||||||
|
// const _t = t('Controller.Main', { returnObjects:true });
|
||||||
|
|
||||||
|
if (Asc.c_oLicenseResult.Expired === licType ||
|
||||||
|
Asc.c_oLicenseResult.Error === licType ||
|
||||||
|
Asc.c_oLicenseResult.ExpiredTrial === licType ||
|
||||||
|
Asc.c_oLicenseResult.NotBefore === licType ||
|
||||||
|
Asc.c_oLicenseResult.ExpiredLimited === licType) {
|
||||||
|
|
||||||
|
f7.dialog.create({
|
||||||
|
title: Asc.c_oLicenseResult.NotBefore === licType ? t('Controller.Main.titleLicenseNotActive') : t('Controller.Main.titleLicenseExp'),
|
||||||
|
text: Asc.c_oLicenseResult.NotBefore === licType ? t('Controller.Main.warnLicenseBefore') : t('Controller.Main.warnLicenseExp')
|
||||||
|
}).open();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.appOptions.canLicense = (licType === Asc.c_oLicenseResult.Success || licType === Asc.c_oLicenseResult.SuccessLimit);
|
||||||
|
|
||||||
|
const storeAppOptions = this.props.storeAppOptions;
|
||||||
|
storeAppOptions.setPermissionOptions(this.document, licType, params, this.permissions, EditorUIController.isSupportEditFeature());
|
||||||
|
this.applyMode(storeAppOptions);
|
||||||
|
|
||||||
|
this.api.asc_LoadDocument();
|
||||||
|
this.api.Resize();
|
||||||
|
};
|
||||||
|
|
||||||
|
processArrayScripts(dep_scripts, promise_get_script)
|
||||||
|
.then(() => {
|
||||||
|
const { t } = this.props;
|
||||||
|
let _translate = t('Controller.Main.SDK', { returnObjects:true })
|
||||||
|
|
||||||
|
if (!(typeof _translate === 'object' && _translate !== null && Object.keys(_translate).length > 0)) {
|
||||||
|
_translate = this.fallbackSdkTranslations
|
||||||
|
}
|
||||||
|
|
||||||
|
this.api = new Asc.asc_docs_api({
|
||||||
|
'id-view': 'editor_sdk',
|
||||||
|
'mobile': true,
|
||||||
|
'translate': _translate
|
||||||
|
});
|
||||||
|
|
||||||
|
Common.Notifications.trigger('engineCreated', this.api);
|
||||||
|
|
||||||
|
this.appOptions = {};
|
||||||
|
this.bindEvents();
|
||||||
|
|
||||||
|
let value = LocalStorage.getItem("ve-settings-fontrender");
|
||||||
|
if (value===null) value = window.devicePixelRatio > 1 ? '1' : '3';
|
||||||
|
this.api.SetFontRenderingMode(parseInt(value));
|
||||||
|
this.api.SetDrawingFreeze(true);
|
||||||
|
Common.Utils.Metric.setCurrentMetric(1); //pt
|
||||||
|
|
||||||
|
Common.Gateway.on('init', loadConfig);
|
||||||
|
Common.Gateway.on('showmessage', this.onExternalMessage.bind(this));
|
||||||
|
Common.Gateway.on('opendocument', loadDocument);
|
||||||
|
Common.Gateway.appReady();
|
||||||
|
|
||||||
|
Common.Gateway.on('internalcommand', function(data) {
|
||||||
|
if (data.command === 'hardBack') {
|
||||||
|
if ($$('.modal-in').length > 0) {
|
||||||
|
if ( !($$('.error-dialog.modal-in').length > 0) ) {
|
||||||
|
f7.dialog.close();
|
||||||
|
}
|
||||||
|
Common.Gateway.internalMessage('hardBack', false);
|
||||||
|
} else
|
||||||
|
Common.Gateway.internalMessage('hardBack', true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Common.Gateway.internalMessage('listenHardBack');
|
||||||
|
}, error => {
|
||||||
|
console.log('promise failed ' + error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( About.developVersion() ) {
|
||||||
|
const script = document.createElement("script");
|
||||||
|
script.src = "../../../../sdkjs/develop/sdkjs/draw/scripts.js";
|
||||||
|
script.async = true;
|
||||||
|
script.onload = on_script_load;
|
||||||
|
script.onerror = () => {
|
||||||
|
console.log('error on load script');
|
||||||
|
};
|
||||||
|
|
||||||
|
document.body.appendChild(script);
|
||||||
|
} else {
|
||||||
|
on_script_load();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
applyMode(appOptions) {
|
||||||
|
this.api.asc_enableKeyEvents(appOptions.isEdit);
|
||||||
|
this.api.asc_setViewMode(!appOptions.isEdit && !appOptions.isRestrictedEdit);
|
||||||
|
(appOptions.isRestrictedEdit && appOptions.canComments) && this.api.asc_setRestriction(Asc.c_oAscRestrictionType.OnlyComments);
|
||||||
|
|
||||||
|
let value = LocalStorage.getItem('ve-mobile-settings-unit');
|
||||||
|
value = (value !== null) ?
|
||||||
|
parseInt(value) :
|
||||||
|
(appOptions.customization && appOptions.customization.unit ? Common.Utils.Metric.c_MetricUnits[appOptions.customization.unit.toLocaleLowerCase()] : Common.Utils.Metric.getDefaultMetric());
|
||||||
|
(value === undefined) && (value = Common.Utils.Metric.getDefaultMetric());
|
||||||
|
Common.Utils.Metric.setCurrentMetric(value);
|
||||||
|
this.api.asc_SetDocumentUnits((value === Common.Utils.Metric.c_MetricUnits.inch) ?
|
||||||
|
Asc.c_oAscDocumentUnits.Inch :
|
||||||
|
((value === Common.Utils.Metric.c_MetricUnits.pt) ? Asc.c_oAscDocumentUnits.Point : Asc.c_oAscDocumentUnits.Millimeter));
|
||||||
|
|
||||||
|
Common.Notifications.trigger('preloader:close');
|
||||||
|
Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], this.ApplyEditRights);
|
||||||
|
|
||||||
|
if (!this._isDocReady) {
|
||||||
|
Common.Notifications.trigger('preloader:beginAction', Asc.c_oAscAsyncActionType['BlockInteraction'], this.LoadingDocument);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message on window close
|
||||||
|
window.onbeforeunload = this.onBeforeUnload.bind(this);
|
||||||
|
window.onunload = this.onUnload.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
loadDefaultMetricSettings() {
|
||||||
|
const appOptions = this.props.storeAppOptions;
|
||||||
|
let region = '';
|
||||||
|
|
||||||
|
if (appOptions.location) {
|
||||||
|
console.log("Obsolete: The 'location' parameter of the 'editorConfig' section is deprecated. Please use 'region' parameter in the 'editorConfig' section instead.");
|
||||||
|
region = appOptions.location;
|
||||||
|
} else if (appOptions.region) {
|
||||||
|
let val = appOptions.region;
|
||||||
|
val = Common.util.LanguageInfo.getLanguages().hasOwnProperty(val) ? Common.util.LanguageInfo.getLocalLanguageName(val)[0] : val;
|
||||||
|
|
||||||
|
if (val && typeof val === 'string') {
|
||||||
|
let arr = val.split(/[\-_]/);
|
||||||
|
if (arr.length > 1) region = arr[arr.length - 1]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let arr = (appOptions.lang || 'en').split(/[\-_]/);
|
||||||
|
|
||||||
|
if (arr.length > 1) region = arr[arr.length - 1]
|
||||||
|
if (!region) {
|
||||||
|
arr = (navigator.language || '').split(/[\-_]/);
|
||||||
|
if (arr.length > 1) region = arr[arr.length - 1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/^(ca|us)$/i.test(region)) {
|
||||||
|
Common.Utils.Metric.setDefaultMetric(Common.Utils.Metric.c_MetricUnits.inch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onBeforeUnload () {
|
||||||
|
LocalStorage.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
onUnload () {
|
||||||
|
}
|
||||||
|
|
||||||
|
bindEvents () {
|
||||||
|
$$(window).on('resize', () => {
|
||||||
|
this.api.Resize();
|
||||||
|
});
|
||||||
|
|
||||||
|
$$(window).on('popup:open sheet:open actions:open searchbar:enable', () => {
|
||||||
|
this.api.asc_enableKeyEvents(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.api.asc_registerCallback('asc_onDocumentContentReady', this.onDocumentContentReady.bind(this));
|
||||||
|
this.api.asc_registerCallback('asc_onDocumentUpdateVersion', this.onUpdateVersion.bind(this));
|
||||||
|
this.api.asc_registerCallback('asc_onServerVersion', this.onServerVersion.bind(this));
|
||||||
|
this.api.asc_registerCallback('asc_onAdvancedOptions', this.onAdvancedOptions.bind(this));
|
||||||
|
this.api.asc_registerCallback('asc_onDocumentName', this.onDocumentName.bind(this));
|
||||||
|
this.api.asc_registerCallback('asc_onPrintUrl', this.onPrintUrl.bind(this));
|
||||||
|
this.api.asc_registerCallback('asc_onPrint', this.onPrint.bind(this));
|
||||||
|
this.api.asc_registerCallback('asc_onMeta', this.onMeta.bind(this));
|
||||||
|
this.api.asc_registerCallback('asc_onDownloadUrl', this.onDownloadUrl.bind(this));
|
||||||
|
|
||||||
|
// Toolbar settings
|
||||||
|
|
||||||
|
const storeToolbarSettings = this.props.storeToolbarSettings;
|
||||||
|
this.api.asc_registerCallback('asc_onCountPages', (count) => {
|
||||||
|
storeToolbarSettings.setCountPages(count);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Visio Info
|
||||||
|
|
||||||
|
const storeVisioInfo = this.props.storeVisioInfo;
|
||||||
|
|
||||||
|
this.api.asc_registerCallback('asc_onMeta', (meta) => {
|
||||||
|
if(meta) {
|
||||||
|
storeVisioInfo.changeTitle(meta.title);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onDocumentContentReady () {
|
||||||
|
if (this._isDocReady)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._isDocReady = true;
|
||||||
|
|
||||||
|
const appOptions = this.props.storeAppOptions;
|
||||||
|
const appSettings = this.props.storeApplicationSettings;
|
||||||
|
|
||||||
|
this.api.SetDrawingFreeze(false);
|
||||||
|
|
||||||
|
Common.Notifications.trigger('preloader:close');
|
||||||
|
Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], this.LoadingDocument);
|
||||||
|
|
||||||
|
this.updateWindowTitle(true);
|
||||||
|
|
||||||
|
if (appOptions.isEdit && this.needToUpdateVersion) {
|
||||||
|
Common.Notifications.trigger('api:disconnect');
|
||||||
|
}
|
||||||
|
|
||||||
|
Common.Gateway.on('processrightschange', this.onProcessRightsChange.bind(this));
|
||||||
|
Common.Gateway.on('downloadas', this.onDownloadAs.bind(this));
|
||||||
|
Common.Gateway.on('requestclose', this.onRequestClose.bind(this));
|
||||||
|
|
||||||
|
Common.Gateway.sendInfo({
|
||||||
|
mode: appOptions.isEdit ? 'edit' : 'view'
|
||||||
|
});
|
||||||
|
|
||||||
|
this.api.Resize();
|
||||||
|
this.api.zoomFitToPage();
|
||||||
|
|
||||||
|
this.applyLicense();
|
||||||
|
|
||||||
|
Common.Gateway.documentReady();
|
||||||
|
f7.emit('resize');
|
||||||
|
|
||||||
|
Common.Notifications.trigger('document:ready');
|
||||||
|
|
||||||
|
appOptions.changeDocReady(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
onLicenseChanged (params) {
|
||||||
|
const appOptions = this.props.storeAppOptions;
|
||||||
|
const licType = params.asc_getLicenseType();
|
||||||
|
if (licType !== undefined && (appOptions.canEdit || appOptions.isRestrictedEdit) && appOptions.config.mode !== 'view' &&
|
||||||
|
(licType === Asc.c_oLicenseResult.Connections || licType === Asc.c_oLicenseResult.UsersCount || licType === Asc.c_oLicenseResult.ConnectionsOS || licType === Asc.c_oLicenseResult.UsersCountOS
|
||||||
|
|| licType === Asc.c_oLicenseResult.SuccessLimit && (appOptions.trialMode & Asc.c_oLicenseMode.Limited) !== 0))
|
||||||
|
this._state.licenseType = licType;
|
||||||
|
|
||||||
|
if (licType !== undefined && appOptions.canLiveView && (licType===Asc.c_oLicenseResult.ConnectionsLive || licType===Asc.c_oLicenseResult.ConnectionsLiveOS||
|
||||||
|
licType===Asc.c_oLicenseResult.UsersViewCount || licType===Asc.c_oLicenseResult.UsersViewCountOS))
|
||||||
|
this._state.licenseType = licType;
|
||||||
|
|
||||||
|
if (this._isDocReady && this._state.licenseType)
|
||||||
|
this.applyLicense();
|
||||||
|
}
|
||||||
|
|
||||||
|
applyLicense () {
|
||||||
|
const { t } = this.props;
|
||||||
|
const _t = t('Controller.Main', {returnObjects:true});
|
||||||
|
|
||||||
|
const warnNoLicense = _t.warnNoLicense.replace(/%1/g, __COMPANY_NAME__);
|
||||||
|
const warnNoLicenseUsers = _t.warnNoLicenseUsers.replace(/%1/g, __COMPANY_NAME__);
|
||||||
|
const textNoLicenseTitle = _t.textNoLicenseTitle.replace(/%1/g, __COMPANY_NAME__);
|
||||||
|
const warnLicenseExceeded = _t.warnLicenseExceeded.replace(/%1/g, __COMPANY_NAME__);
|
||||||
|
const warnLicenseUsersExceeded = _t.warnLicenseUsersExceeded.replace(/%1/g, __COMPANY_NAME__);
|
||||||
|
|
||||||
|
const appOptions = this.props.storeAppOptions;
|
||||||
|
if (appOptions.config.mode !== 'view' && !EditorUIController.isSupportEditFeature()) {
|
||||||
|
// let value = LocalStorage.getItem("ve-opensource-warning");
|
||||||
|
// value = (value !== null) ? parseInt(value) : 0;
|
||||||
|
// const now = (new Date).getTime();
|
||||||
|
// if (now - value > 86400000) {
|
||||||
|
// LocalStorage.setItem("ve-opensource-warning", now);
|
||||||
|
// f7.dialog.create({
|
||||||
|
// title: _t.notcriticalErrorTitle,
|
||||||
|
// text : _t.errorOpensource,
|
||||||
|
// buttons: [{ text: _t.textOk }]
|
||||||
|
// }).open();
|
||||||
|
// }
|
||||||
|
// Common.Notifications.trigger('toolbar:activatecontrols');
|
||||||
|
// return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (appOptions.config.mode === 'view') {
|
||||||
|
if (appOptions.canLiveView && (this._state.licenseType===Asc.c_oLicenseResult.ConnectionsLive || this._state.licenseType===Asc.c_oLicenseResult.ConnectionsLiveOS ||
|
||||||
|
this._state.licenseType===Asc.c_oLicenseResult.UsersViewCount || this._state.licenseType===Asc.c_oLicenseResult.UsersViewCountOS ||
|
||||||
|
!appOptions.isAnonymousSupport && !!appOptions.config.user.anonymous)) {
|
||||||
|
appOptions.canLiveView = false;
|
||||||
|
this.api.asc_SetFastCollaborative(false);
|
||||||
|
}
|
||||||
|
Common.Notifications.trigger('toolbar:activatecontrols');
|
||||||
|
} else if (!appOptions.isAnonymousSupport && !!appOptions.config.user.anonymous) {
|
||||||
|
Common.Notifications.trigger('toolbar:activatecontrols');
|
||||||
|
this.api.asc_coAuthoringDisconnect();
|
||||||
|
Common.Notifications.trigger('api:disconnect');
|
||||||
|
f7.dialog.create({
|
||||||
|
title: _t.notcriticalErrorTitle,
|
||||||
|
text : _t.warnLicenseAnonymous,
|
||||||
|
buttons: [{ text: _t.textOk }]
|
||||||
|
}).open();
|
||||||
|
} else if (this._state.licenseType) {
|
||||||
|
let license = this._state.licenseType;
|
||||||
|
let buttons = [{ text: _t.textOk }];
|
||||||
|
if ((appOptions.trialMode & Asc.c_oLicenseMode.Limited) !== 0 &&
|
||||||
|
(license === Asc.c_oLicenseResult.SuccessLimit ||
|
||||||
|
appOptions.permissionsLicense === Asc.c_oLicenseResult.SuccessLimit)
|
||||||
|
) {
|
||||||
|
license = _t.warnLicenseLimitedRenewed;
|
||||||
|
} else if (license === Asc.c_oLicenseResult.Connections || license === Asc.c_oLicenseResult.UsersCount) {
|
||||||
|
license = (license===Asc.c_oLicenseResult.Connections) ? warnLicenseExceeded : warnLicenseUsersExceeded;
|
||||||
|
} else {
|
||||||
|
license = (license === Asc.c_oLicenseResult.ConnectionsOS) ? warnNoLicense : warnNoLicenseUsers;
|
||||||
|
buttons = [{
|
||||||
|
text: _t.textBuyNow,
|
||||||
|
bold: true,
|
||||||
|
onClick: function() {
|
||||||
|
window.open(`${__PUBLISHER_URL__}`, "_blank");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: _t.textContactUs,
|
||||||
|
onClick: function() {
|
||||||
|
window.open(`mailto:${__SALES_EMAIL__}`, "_blank");
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
if (this._state.licenseType === Asc.c_oLicenseResult.SuccessLimit) {
|
||||||
|
Common.Notifications.trigger('toolbar:activatecontrols');
|
||||||
|
} else {
|
||||||
|
Common.Notifications.trigger('toolbar:activatecontrols');
|
||||||
|
this.api.asc_coAuthoringDisconnect();
|
||||||
|
Common.Notifications.trigger('api:disconnect');
|
||||||
|
}
|
||||||
|
|
||||||
|
let value = LocalStorage.getItem("ve-license-warning");
|
||||||
|
value = (value !== null) ? parseInt(value) : 0;
|
||||||
|
const now = (new Date).getTime();
|
||||||
|
|
||||||
|
if (now - value > 86400000) {
|
||||||
|
LocalStorage.setItem("ve-license-warning", now);
|
||||||
|
f7.dialog.create({
|
||||||
|
title: textNoLicenseTitle,
|
||||||
|
text : license,
|
||||||
|
buttons: buttons
|
||||||
|
}).open();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!appOptions.isDesktopApp && !appOptions.canBrandingExt &&
|
||||||
|
appOptions.config && appOptions.config.customization && (appOptions.config.customization.loaderName || appOptions.config.customization.loaderLogo)) {
|
||||||
|
f7.dialog.create({
|
||||||
|
title: _t.textPaidFeature,
|
||||||
|
text : _t.textCustomLoader,
|
||||||
|
buttons: [{
|
||||||
|
text: _t.textContactUs,
|
||||||
|
bold: true,
|
||||||
|
onClick: () => {
|
||||||
|
window.open(`mailto:${__SALES_EMAIL__}`, "_blank");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ text: _t.textClose }]
|
||||||
|
}).open();
|
||||||
|
}
|
||||||
|
Common.Notifications.trigger('toolbar:activatecontrols');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onUpdateVersion (callback) {
|
||||||
|
const { t } = this.props;
|
||||||
|
const _t = t('Controller.Main', {returnObjects:true});
|
||||||
|
|
||||||
|
this.needToUpdateVersion = true;
|
||||||
|
Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], this.LoadingDocument);
|
||||||
|
|
||||||
|
f7.dialog.alert(
|
||||||
|
_t.errorUpdateVersion,
|
||||||
|
_t.titleUpdateVersion,
|
||||||
|
() => {
|
||||||
|
Common.Gateway.updateVersion();
|
||||||
|
if (callback) {
|
||||||
|
callback.call(this);
|
||||||
|
}
|
||||||
|
Common.Notifications.trigger('preloader:beginAction', Asc.c_oAscAsyncActionType['BlockInteraction'], this.LoadingDocument);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onServerVersion (buildVersion) {
|
||||||
|
if (this.changeServerVersion) return true;
|
||||||
|
const { t } = this.props;
|
||||||
|
const _t = t('Controller.Main', {returnObjects:true});
|
||||||
|
|
||||||
|
if (About.appVersion() !== buildVersion && !window.compareVersions) {
|
||||||
|
this.changeServerVersion = true;
|
||||||
|
f7.dialog.alert(
|
||||||
|
_t.errorServerVersion,
|
||||||
|
_t.titleServerVersion,
|
||||||
|
() => {
|
||||||
|
setTimeout(() => {Common.Gateway.updateVersion()}, 0);
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onAdvancedOptions (type, advOptions) {
|
||||||
|
const { t } = this.props;
|
||||||
|
const _t = t('Controller.Main', {returnObjects:true});
|
||||||
|
|
||||||
|
if ($$('.dlg-adv-options.modal-in').length > 0) return;
|
||||||
|
|
||||||
|
if (type == Asc.c_oAscAdvancedOptionsID.DRM) {
|
||||||
|
Common.Notifications.trigger('preloader:close');
|
||||||
|
Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], this.LoadingDocument, true);
|
||||||
|
|
||||||
|
const buttons = [{
|
||||||
|
text: _t.textOk,
|
||||||
|
bold: true,
|
||||||
|
onClick: () => {
|
||||||
|
const password = document.getElementById('modal-password').value;
|
||||||
|
this.api.asc_setAdvancedOptions(type, new Asc.asc_CDRMAdvancedOptions(password));
|
||||||
|
|
||||||
|
if (!this._isDocReady) {
|
||||||
|
Common.Notifications.trigger('preloader:beginAction', Asc.c_oAscAsyncActionType['BlockInteraction'], this.LoadingDocument);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
if(this.isDRM) {
|
||||||
|
f7.dialog.create({
|
||||||
|
text: _t.txtIncorrectPwd,
|
||||||
|
buttons : [{
|
||||||
|
text: _t.textOk,
|
||||||
|
bold: true,
|
||||||
|
}]
|
||||||
|
}).open();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.storeAppOptions.canRequestClose)
|
||||||
|
buttons.push({
|
||||||
|
text: _t.closeButtonText,
|
||||||
|
onClick: () => {
|
||||||
|
Common.Gateway.requestClose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
f7.dialog.create({
|
||||||
|
title: _t.advDRMOptions,
|
||||||
|
text: _t.textOpenFile,
|
||||||
|
content: Device.ios ?
|
||||||
|
'<div class="input-field"><input type="password" class="modal-text-input" name="modal-password" placeholder="' + _t.advDRMPassword + '" id="modal-password"></div>' : '<div class="input-field"><div class="inputs-list list inline-labels"><ul><li><div class="item-content item-input"><div class="item-inner"><div class="item-input-wrap"><input type="password" name="modal-password" id="modal-password" placeholder=' + _t.advDRMPassword + '></div></div></div></li></ul></div></div>',
|
||||||
|
buttons: buttons,
|
||||||
|
cssClass: 'dlg-adv-options'
|
||||||
|
}).open();
|
||||||
|
this.isDRM = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onDocumentName () {
|
||||||
|
this.updateWindowTitle(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateWindowTitle (force) {
|
||||||
|
const isModified = this.api.isDocumentModified();
|
||||||
|
if (this._state.isDocModified !== isModified || force) {
|
||||||
|
const title = this.defaultTitleText;
|
||||||
|
|
||||||
|
if (window.document.title !== title) {
|
||||||
|
window.document.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._isDocReady && (this._state.isDocModified !== isModified) && Common.Gateway.setDocumentModified(isModified);
|
||||||
|
this._state.isDocModified = isModified;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onPrint () {
|
||||||
|
if (!this.props.storeAppOptions.canPrint) return;
|
||||||
|
|
||||||
|
if (this.api)
|
||||||
|
this.api.asc_Print();
|
||||||
|
Common.component.Analytics.trackEvent('Print');
|
||||||
|
}
|
||||||
|
|
||||||
|
onPrintUrl (url) {
|
||||||
|
if (this.iframePrint) {
|
||||||
|
this.iframePrint.parentNode.removeChild(this.iframePrint);
|
||||||
|
this.iframePrint = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.iframePrint) {
|
||||||
|
this.iframePrint = document.createElement("iframe");
|
||||||
|
this.iframePrint.id = "id-print-frame";
|
||||||
|
this.iframePrint.style.display = 'none';
|
||||||
|
this.iframePrint.style.visibility = "hidden";
|
||||||
|
this.iframePrint.style.position = "fixed";
|
||||||
|
this.iframePrint.style.right = "0";
|
||||||
|
this.iframePrint.style.bottom = "0";
|
||||||
|
document.body.appendChild(this.iframePrint);
|
||||||
|
this.iframePrint.onload = function() {
|
||||||
|
this.iframePrint.contentWindow.focus();
|
||||||
|
this.iframePrint.contentWindow.print();
|
||||||
|
this.iframePrint.contentWindow.blur();
|
||||||
|
window.focus();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url) {
|
||||||
|
this.iframePrint.src = url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMeta (meta) {
|
||||||
|
this.updateWindowTitle(true);
|
||||||
|
Common.Gateway.metaChange(meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
onExternalMessage (msg) {
|
||||||
|
if (msg && msg.msg) {
|
||||||
|
msg.msg = (msg.msg).toString();
|
||||||
|
f7.notification.create({
|
||||||
|
//title: uiApp.params.modalTitle,
|
||||||
|
text: [msg.msg.charAt(0).toUpperCase() + msg.msg.substring(1)],
|
||||||
|
closeButton: true
|
||||||
|
}).open();
|
||||||
|
|
||||||
|
Common.component.Analytics.trackEvent('External Error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onProcessRightsChange (data) {
|
||||||
|
if (data && data.enabled === false) {
|
||||||
|
const appOptions = this.props.storeAppOptions;
|
||||||
|
const old_rights = appOptions.lostEditingRights;
|
||||||
|
appOptions.changeEditingRights(!old_rights);
|
||||||
|
this.api.asc_coAuthoringDisconnect();
|
||||||
|
Common.Notifications.trigger('api:disconnect');
|
||||||
|
|
||||||
|
if (!old_rights) {
|
||||||
|
const { t } = this.props;
|
||||||
|
const _t = t('Controller.Main', {returnObjects:true});
|
||||||
|
f7.dialog.alert(
|
||||||
|
(!data.message) ? _t.warnProcessRightsChange : data.message,
|
||||||
|
_t.notcriticalErrorTitle,
|
||||||
|
() => { appOptions.changeEditingRights(false); }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onDownloadUrl(url, fileType) {
|
||||||
|
if (this._state.isFromGatewayDownloadAs) {
|
||||||
|
Common.Gateway.downloadAs(url, fileType);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._state.isFromGatewayDownloadAs = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onDownloadAs(format) {
|
||||||
|
const appOptions = this.props.storeAppOptions;
|
||||||
|
|
||||||
|
if (!appOptions.canDownload) {
|
||||||
|
const { t } = this.props;
|
||||||
|
const _t = t('Controller.Main', { returnObjects:true });
|
||||||
|
Common.Gateway.reportError(Asc.c_oAscError.ID.AccessDeny, _t.errorAccessDeny);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._state.isFromGatewayDownloadAs = true;
|
||||||
|
|
||||||
|
let _format = (format && (typeof format == 'string')) ? Asc.c_oAscFileType[format.toUpperCase()] : null,
|
||||||
|
_supported = [
|
||||||
|
Asc.c_oAscFileType.VSDX,
|
||||||
|
Asc.c_oAscFileType.PDF,
|
||||||
|
Asc.c_oAscFileType.PDFA,
|
||||||
|
Asc.c_oAscFileType.PNG,
|
||||||
|
Asc.c_oAscFileType.JPG
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!_format || _supported.indexOf(_format) < 0)
|
||||||
|
_format = Asc.c_oAscFileType.VSDX;
|
||||||
|
|
||||||
|
const options = new Asc.asc_CDownloadOptions(_format, true);
|
||||||
|
options.asc_setIsSaveAs(true);
|
||||||
|
this.api.asc_DownloadAs(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
onRequestClose () {
|
||||||
|
const { t } = this.props;
|
||||||
|
const _t = t("Toolbar", { returnObjects: true });
|
||||||
|
|
||||||
|
if (this.api.isDocumentModified()) {
|
||||||
|
this.api.asc_stopSaving();
|
||||||
|
|
||||||
|
f7.dialog.create({
|
||||||
|
title: _t.dlgLeaveTitleText,
|
||||||
|
text: _t.dlgLeaveMsgText,
|
||||||
|
verticalButtons: true,
|
||||||
|
buttons : [
|
||||||
|
{
|
||||||
|
text: _t.leaveButtonText,
|
||||||
|
onClick: () => {
|
||||||
|
this.api.asc_undoAllChanges();
|
||||||
|
this.api.asc_continueSaving();
|
||||||
|
Common.Gateway.requestClose();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: _t.stayButtonText,
|
||||||
|
bold: true,
|
||||||
|
onClick: () => {
|
||||||
|
this.api.asc_continueSaving();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}).open();
|
||||||
|
} else {
|
||||||
|
Common.Gateway.requestClose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<LongActionsController />
|
||||||
|
<ErrorController LoadingDocument={this.LoadingDocument}/>
|
||||||
|
<CollaborationController />
|
||||||
|
<Themes />
|
||||||
|
</Fragment>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount () {
|
||||||
|
Common.EditorApi = {get: () => this.api};
|
||||||
|
this.initSdk();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const translated = withTranslation()(MainController);
|
||||||
|
export {translated as MainController};
|
||||||
234
apps/visioeditor/mobile/src/controller/Toolbar.jsx
Normal file
234
apps/visioeditor/mobile/src/controller/Toolbar.jsx
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { inject, observer } from 'mobx-react';
|
||||||
|
import { f7 } from 'framework7-react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import ToolbarView from "../view/Toolbar";
|
||||||
|
import { Device } from '../../../../common/mobile/utils/device';
|
||||||
|
|
||||||
|
const ToolbarController = inject('storeAppOptions', 'users', 'storeToolbarSettings', 'storeVisioInfo')(observer(props => {
|
||||||
|
const {t} = useTranslation();
|
||||||
|
const _t = t("Toolbar", { returnObjects: true });
|
||||||
|
const appOptions = props.storeAppOptions;
|
||||||
|
const isDisconnected = props.users.isDisconnected;
|
||||||
|
const displayCollaboration = props.users.hasEditUsers || appOptions.canViewComments;
|
||||||
|
|
||||||
|
const isEditLocked = true;
|
||||||
|
|
||||||
|
const storeToolbarSettings = props.storeToolbarSettings;
|
||||||
|
const disabledControls = storeToolbarSettings.disabledControls;
|
||||||
|
const disabledSettings = storeToolbarSettings.disabledSettings;
|
||||||
|
|
||||||
|
const storeVisioInfo = props.storeVisioInfo;
|
||||||
|
const docTitle = storeVisioInfo.dataDoc?.title ?? '';
|
||||||
|
const docExt = storeVisioInfo.dataDoc?.fileType ?? '';
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
Common.Gateway.on('init', loadConfig);
|
||||||
|
Common.Notifications.on('toolbar:activatecontrols', activateControls);
|
||||||
|
Common.Notifications.on('goback', goBack);
|
||||||
|
Common.Notifications.on('close', onRequestClose);
|
||||||
|
|
||||||
|
if (isDisconnected) {
|
||||||
|
f7.popover.close();
|
||||||
|
f7.sheet.close();
|
||||||
|
f7.popup.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
Common.Notifications.off('toolbar:activatecontrols', activateControls);
|
||||||
|
Common.Notifications.off('goback', goBack);
|
||||||
|
Common.Notifications.off('close', onRequestClose);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Back button
|
||||||
|
const [isShowBack, setShowBack] = useState(appOptions.canBackToFolder);
|
||||||
|
const loadConfig = (data) => {
|
||||||
|
if (data && data.config && data.config.canBackToFolder !== false &&
|
||||||
|
data.config.customization && data.config.customization.goback) {
|
||||||
|
const canback = data.config.customization.close === undefined ?
|
||||||
|
data.config.customization.goback.url || data.config.customization.goback.requestClose && data.config.canRequestClose :
|
||||||
|
data.config.customization.goback.url && !data.config.customization.goback.requestClose;
|
||||||
|
canback && setShowBack(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onRequestClose = () => {
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
|
||||||
|
if (api.isDocumentModified()) {
|
||||||
|
api.asc_stopSaving();
|
||||||
|
|
||||||
|
f7.dialog.create({
|
||||||
|
title : _t.dlgLeaveTitleText,
|
||||||
|
text : _t.dlgLeaveMsgText,
|
||||||
|
verticalButtons: true,
|
||||||
|
buttons : [
|
||||||
|
{
|
||||||
|
text: _t.leaveButtonText,
|
||||||
|
onClick: () => {
|
||||||
|
api.asc_undoAllChanges();
|
||||||
|
api.asc_continueSaving();
|
||||||
|
Common.Gateway.requestClose();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: _t.stayButtonText,
|
||||||
|
bold: true,
|
||||||
|
onClick: () => {
|
||||||
|
api.asc_continueSaving();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}).open();
|
||||||
|
} else {
|
||||||
|
Common.Gateway.requestClose();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const goBack = (current) => {
|
||||||
|
if (appOptions.customization.goback.requestClose && appOptions.canRequestClose) {
|
||||||
|
onRequestClose();
|
||||||
|
} else {
|
||||||
|
const href = appOptions.customization.goback.url;
|
||||||
|
|
||||||
|
if (!current && appOptions.customization.goback.blank !== false) {
|
||||||
|
window.open(href, "_blank");
|
||||||
|
} else {
|
||||||
|
parent.location.href = href;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const activateControls = () => {
|
||||||
|
storeToolbarSettings.setDisabledControls(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const changeTitleHandler = () => {
|
||||||
|
if(!appOptions.canRename) return;
|
||||||
|
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
api.asc_enableKeyEvents(true);
|
||||||
|
|
||||||
|
f7.dialog.create({
|
||||||
|
title: t('Toolbar.textRenameFile'),
|
||||||
|
text : t('Toolbar.textEnterNewFileName'),
|
||||||
|
content: Device.ios ?
|
||||||
|
`<div class="input-field">
|
||||||
|
<input type="text" class="modal-text-input" name="modal-title" id="modal-title">
|
||||||
|
</div>` :
|
||||||
|
`<div class="input-field modal-title">
|
||||||
|
<div class="inputs-list list inline-labels">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="item-content item-input">
|
||||||
|
<div class="item-inner">
|
||||||
|
<div class="item-input-wrap">
|
||||||
|
<input type="text" name="modal-title" id="modal-title">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>`,
|
||||||
|
cssClass: 'dlg-adv-options',
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
text: t('View.Edit.textCancel')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: t('View.Edit.textOk'),
|
||||||
|
cssClass: 'btn-change-title',
|
||||||
|
bold: true,
|
||||||
|
close: false,
|
||||||
|
onClick: () => {
|
||||||
|
const titleFieldValue = document.querySelector('#modal-title').value;
|
||||||
|
|
||||||
|
if(titleFieldValue.trim().length) {
|
||||||
|
changeTitle(titleFieldValue);
|
||||||
|
f7.dialog.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
on: {
|
||||||
|
opened: () => {
|
||||||
|
const nameDoc = docTitle.split('.')[0];
|
||||||
|
const titleField = document.querySelector('#modal-title');
|
||||||
|
const btnChangeTitle = document.querySelector('.btn-change-title');
|
||||||
|
|
||||||
|
titleField.value = nameDoc;
|
||||||
|
titleField.focus();
|
||||||
|
titleField.select();
|
||||||
|
|
||||||
|
titleField.addEventListener('input', () => {
|
||||||
|
if(titleField.value.trim().length) {
|
||||||
|
btnChangeTitle.classList.remove('disabled');
|
||||||
|
} else {
|
||||||
|
btnChangeTitle.classList.add('disabled');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).open();
|
||||||
|
}
|
||||||
|
|
||||||
|
const cutDocName = name => {
|
||||||
|
if(name.length <= docExt.length) return name;
|
||||||
|
const idx = name.length - docExt.length;
|
||||||
|
|
||||||
|
return name.substring(idx) == docExt ? name.substring(0, idx) : name;
|
||||||
|
};
|
||||||
|
|
||||||
|
const changeTitle = (name) => {
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
const currentTitle = `${name}.${docExt}`;
|
||||||
|
let formatName = name.trim();
|
||||||
|
|
||||||
|
if(formatName.length > 0 && cutDocName(currentTitle) !== formatName) {
|
||||||
|
if(/[\t*\+:\"<>?|\\\\/]/gim.test(formatName)) {
|
||||||
|
f7.dialog.create({
|
||||||
|
title: t('View.Edit.notcriticalErrorTitle'),
|
||||||
|
text: t('View.Edit.textInvalidName') + '*+:\"<>?|\/',
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
text: t('View.Edit.textOk'),
|
||||||
|
close: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}).open();
|
||||||
|
} else {
|
||||||
|
const wopi = appOptions.wopi;
|
||||||
|
formatName = cutDocName(formatName);
|
||||||
|
|
||||||
|
if(wopi) {
|
||||||
|
api.asc_wopi_renameFile(formatName);
|
||||||
|
} else {
|
||||||
|
Common.Gateway.requestRename(formatName);
|
||||||
|
}
|
||||||
|
|
||||||
|
const newTitle = `${formatName}.${docExt}`;
|
||||||
|
storeVisioInfo.changeTitle(newTitle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ToolbarView
|
||||||
|
openOptions={props.openOptions}
|
||||||
|
isEdit={appOptions.isEdit}
|
||||||
|
docTitle={docTitle}
|
||||||
|
isShowBack={isShowBack}
|
||||||
|
disabledEdit={isEditLocked}
|
||||||
|
disabledControls={disabledControls}
|
||||||
|
disabledSettings={disabledSettings}
|
||||||
|
displayCollaboration={displayCollaboration}
|
||||||
|
isDisconnected={isDisconnected}
|
||||||
|
isOpenModal={props.isOpenModal}
|
||||||
|
changeTitleHandler={changeTitleHandler}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}));
|
||||||
|
|
||||||
|
export {ToolbarController as Toolbar};
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
import React, { Component } from "react";
|
||||||
|
import { ApplicationSettings } from "../../view/settings/ApplicationSettings";
|
||||||
|
import { LocalStorage } from '../../../../../common/mobile/utils/LocalStorage.mjs';
|
||||||
|
import {observer, inject} from "mobx-react";
|
||||||
|
import { ThemesContext } from "../../../../../common/mobile/lib/controller/Themes";
|
||||||
|
import { withTranslation } from 'react-i18next';
|
||||||
|
import { f7 } from "framework7-react";
|
||||||
|
|
||||||
|
class ApplicationSettingsController extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
static contextType = ThemesContext;
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<ApplicationSettings
|
||||||
|
changeTheme={this.context.changeTheme}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default inject("storeApplicationSettings", "storeAppOptions")(observer(withTranslation()(ApplicationSettingsController)));
|
||||||
36
apps/visioeditor/mobile/src/controller/settings/Download.jsx
Normal file
36
apps/visioeditor/mobile/src/controller/settings/Download.jsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import React, { Component } from "react";
|
||||||
|
import Download from "../../view/settings/Download";
|
||||||
|
import { Device } from '../../../../../common/mobile/utils/device';
|
||||||
|
import { f7 } from 'framework7-react';
|
||||||
|
|
||||||
|
class DownloadController extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.onSaveFormat = this.onSaveFormat.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
closeModal() {
|
||||||
|
if (Device.phone) {
|
||||||
|
f7.sheet.close('.settings-popup', true);
|
||||||
|
} else {
|
||||||
|
f7.popover.close('#settings-popover');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onSaveFormat(format) {
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
if(format) {
|
||||||
|
api.asc_DownloadAs(new Asc.asc_CDownloadOptions(format));
|
||||||
|
}
|
||||||
|
this.closeModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Download onSaveFormat={this.onSaveFormat} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default DownloadController;
|
||||||
177
apps/visioeditor/mobile/src/controller/settings/Settings.jsx
Normal file
177
apps/visioeditor/mobile/src/controller/settings/Settings.jsx
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
import React, { createContext } from 'react';
|
||||||
|
import { Device } from '../../../../../common/mobile/utils/device';
|
||||||
|
import SettingsView from '../../view/settings/Settings';
|
||||||
|
import { f7 } from 'framework7-react';
|
||||||
|
import { observer, inject } from "mobx-react";
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
export const SettingsContext = createContext();
|
||||||
|
|
||||||
|
const SettingsController = props => {
|
||||||
|
const appOptions = props.storeAppOptions;
|
||||||
|
const storeVisioInfo = props.storeVisioInfo;
|
||||||
|
const docExt = storeVisioInfo.dataDoc.fileType;
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const closeModal = () => {
|
||||||
|
if (Device.phone) {
|
||||||
|
f7.sheet.close('.settings-popup', false);
|
||||||
|
} else {
|
||||||
|
f7.popover.close('#settings-popover', false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPrint = () => {
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
|
||||||
|
closeModal();
|
||||||
|
setTimeout(() => {
|
||||||
|
api.asc_Print();
|
||||||
|
}, 400);
|
||||||
|
};
|
||||||
|
|
||||||
|
const showHelp = () => {
|
||||||
|
// let url = '{{HELP_URL}}';
|
||||||
|
let url = __HELP_URL__;
|
||||||
|
// let url = 'https://helpcenter.onlyoffice.com';
|
||||||
|
|
||||||
|
if (url.charAt(url.length-1) !== '/') {
|
||||||
|
url += '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Device.sailfish || Device.android) {
|
||||||
|
url+='mobile-applications/documents/mobile-web-editors/android/index.aspx';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
url+='mobile-applications/documents/mobile-web-editors/ios/index.aspx';
|
||||||
|
}
|
||||||
|
|
||||||
|
closeModal();
|
||||||
|
window.open(url, "_blank");
|
||||||
|
};
|
||||||
|
|
||||||
|
const showFeedback = () => {
|
||||||
|
let config = props.storeAppOptions.config;
|
||||||
|
|
||||||
|
closeModal();
|
||||||
|
if(config && !!config.feedback && !!config.feedback.url) {
|
||||||
|
window.open(config.feedback.url, "_blank");
|
||||||
|
} else window.open(__SUPPORT_URL__, "_blank");
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDownloadOrigin = () => {
|
||||||
|
closeModal();
|
||||||
|
setTimeout(() => {
|
||||||
|
Common.EditorApi.get().asc_DownloadOrigin();
|
||||||
|
}, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
const changeTitleHandler = () => {
|
||||||
|
if(!appOptions.canRename) return;
|
||||||
|
|
||||||
|
const docTitle = storeVisioInfo.dataDoc?.title ?? '';
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
api.asc_enableKeyEvents(true);
|
||||||
|
|
||||||
|
f7.dialog.create({
|
||||||
|
title: t('Toolbar.textRenameFile'),
|
||||||
|
text : t('Toolbar.textEnterNewFileName'),
|
||||||
|
content: Device.ios ?
|
||||||
|
'<div class="input-field"><input type="text" class="modal-text-input" name="modal-title" id="modal-title"></div>' : '<div class="input-field modal-title"><div class="inputs-list list inline-labels"><ul><li><div class="item-content item-input"><div class="item-inner"><div class="item-input-wrap"><input type="text" name="modal-title" id="modal-title"></div></div></div></li></ul></div></div>',
|
||||||
|
cssClass: 'dlg-adv-options',
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
text: t('View.Edit.textCancel')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: t('View.Edit.textOk'),
|
||||||
|
cssClass: 'btn-change-title',
|
||||||
|
bold: true,
|
||||||
|
close: false,
|
||||||
|
onClick: () => {
|
||||||
|
const titleFieldValue = document.querySelector('#modal-title').value;
|
||||||
|
|
||||||
|
if(titleFieldValue.trim().length) {
|
||||||
|
changeTitle(titleFieldValue);
|
||||||
|
f7.dialog.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
on: {
|
||||||
|
opened: () => {
|
||||||
|
const nameDoc = docTitle.split('.')[0];
|
||||||
|
const titleField = document.querySelector('#modal-title');
|
||||||
|
const btnChangeTitle = document.querySelector('.btn-change-title');
|
||||||
|
|
||||||
|
titleField.value = nameDoc;
|
||||||
|
titleField.focus();
|
||||||
|
titleField.select();
|
||||||
|
|
||||||
|
titleField.addEventListener('input', () => {
|
||||||
|
if(titleField.value.trim().length) {
|
||||||
|
btnChangeTitle.classList.remove('disabled');
|
||||||
|
} else {
|
||||||
|
btnChangeTitle.classList.add('disabled');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).open();
|
||||||
|
};
|
||||||
|
|
||||||
|
const cutDocName = name => {
|
||||||
|
if(name.length <= docExt.length) return name;
|
||||||
|
const idx = name.length - docExt.length;
|
||||||
|
|
||||||
|
return name.substring(idx) == docExt ? name.substring(0, idx) : name;
|
||||||
|
};
|
||||||
|
|
||||||
|
const changeTitle = (name) => {
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
const currentTitle = `${name}.${docExt}`;
|
||||||
|
let formatName = name.trim();
|
||||||
|
|
||||||
|
if(formatName.length > 0 && cutDocName(currentTitle) !== formatName) {
|
||||||
|
if(/[\t*\+:\"<>?|\\\\/]/gim.test(formatName)) {
|
||||||
|
f7.dialog.create({
|
||||||
|
title: t('View.Edit.notcriticalErrorTitle'),
|
||||||
|
text: t('View.Edit.textInvalidName') + '*+:\"<>?|\/',
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
text: t('View.Edit.textOk'),
|
||||||
|
close: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}).open();
|
||||||
|
} else {
|
||||||
|
const wopi = appOptions.wopi;
|
||||||
|
formatName = cutDocName(formatName);
|
||||||
|
|
||||||
|
if(wopi) {
|
||||||
|
api.asc_wopi_renameFile(formatName);
|
||||||
|
} else {
|
||||||
|
Common.Gateway.requestRename(formatName);
|
||||||
|
}
|
||||||
|
|
||||||
|
const newTitle = `${formatName}.${docExt}`;
|
||||||
|
storeVisioInfo.changeTitle(newTitle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SettingsContext.Provider value={{
|
||||||
|
onPrint,
|
||||||
|
showHelp,
|
||||||
|
showFeedback,
|
||||||
|
onDownloadOrigin,
|
||||||
|
closeModal,
|
||||||
|
changeTitleHandler
|
||||||
|
}}>
|
||||||
|
<SettingsView />
|
||||||
|
</SettingsContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default inject("storeAppOptions", "storeVisioInfo")(observer(SettingsController));
|
||||||
102
apps/visioeditor/mobile/src/controller/settings/VisioInfo.jsx
Normal file
102
apps/visioeditor/mobile/src/controller/settings/VisioInfo.jsx
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import React, { Component } from "react";
|
||||||
|
import VisioInfo from "../../view/settings/VisioInfo";
|
||||||
|
import { observer, inject } from "mobx-react";
|
||||||
|
|
||||||
|
class VisioInfoController extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.docProps = this.getDocProps();
|
||||||
|
|
||||||
|
if(this.docProps) {
|
||||||
|
this.modified = this.getModified();
|
||||||
|
this.modifiedBy = this.getModifiedBy();
|
||||||
|
this.creators = this.getCreators();
|
||||||
|
this.title = this.getTitle();
|
||||||
|
this.subject = this.getSubject();
|
||||||
|
this.description = this.getDescription();
|
||||||
|
this.created = this.getCreated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getDocProps() {
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
return api.asc_getCoreProps();
|
||||||
|
}
|
||||||
|
|
||||||
|
getAppProps() {
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
const appProps = api.asc_getAppProps();
|
||||||
|
|
||||||
|
if (appProps) {
|
||||||
|
return `${!appProps.asc_getApplication() ? '' : appProps.asc_getApplication() + ' ' + appProps.asc_getAppVersion()}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getModified() {
|
||||||
|
let valueModified = this.docProps.asc_getModified();
|
||||||
|
const _lang = this.props.storeAppOptions.lang;
|
||||||
|
|
||||||
|
if (valueModified) {
|
||||||
|
return (
|
||||||
|
valueModified.toLocaleString(_lang, {
|
||||||
|
year: "numeric",
|
||||||
|
month: "2-digit",
|
||||||
|
day: "2-digit",
|
||||||
|
}) +
|
||||||
|
" " +
|
||||||
|
valueModified.toLocaleTimeString(_lang, { timeStyle: "short" })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getModifiedBy() {
|
||||||
|
let valueModifiedBy = this.docProps.asc_getLastModifiedBy();
|
||||||
|
|
||||||
|
if (valueModifiedBy) {
|
||||||
|
return AscCommon.UserInfoParser.getParsedName(valueModifiedBy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getCreators() {
|
||||||
|
return this.docProps.asc_getCreator();
|
||||||
|
}
|
||||||
|
|
||||||
|
getTitle() {
|
||||||
|
return this.docProps.asc_getTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
getSubject() {
|
||||||
|
return this.docProps.asc_getSubject();
|
||||||
|
}
|
||||||
|
|
||||||
|
getDescription() {
|
||||||
|
return this.docProps.asc_getDescription();
|
||||||
|
}
|
||||||
|
|
||||||
|
getCreated() {
|
||||||
|
let value = this.docProps.asc_getCreated();
|
||||||
|
const _lang = this.props.storeAppOptions.lang;
|
||||||
|
|
||||||
|
if(value) {
|
||||||
|
return value.toLocaleString(_lang, {year: 'numeric', month: '2-digit', day: '2-digit'}) + ' ' + value.toLocaleTimeString(_lang, {timeStyle: 'short'});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<VisioInfo
|
||||||
|
getAppProps={this.getAppProps}
|
||||||
|
modified={this.modified}
|
||||||
|
modifiedBy={this.modifiedBy}
|
||||||
|
creators={this.creators}
|
||||||
|
created={this.created}
|
||||||
|
title={this.title}
|
||||||
|
subject={this.subject}
|
||||||
|
description={this.description}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default inject("storeAppOptions")(observer(VisioInfoController));
|
||||||
94
apps/visioeditor/mobile/src/index_dev.html
Normal file
94
apps/visioeditor/mobile/src/index_dev.html
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="default-src * 'self' 'unsafe-inline' 'unsafe-eval' data: blob:">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui, viewport-fit=cover">
|
||||||
|
|
||||||
|
<meta name="theme-color" content="#007aff">
|
||||||
|
<meta name="format-detection" content="telephone=no">
|
||||||
|
<meta name="msapplication-tap-highlight" content="no">
|
||||||
|
<title>Visio Editor</title>
|
||||||
|
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||||
|
<link rel="apple-touch-icon" href="static/icons/apple-touch-icon.png">
|
||||||
|
<link rel="icon" href="static/icons/favicon.png">
|
||||||
|
|
||||||
|
<% if (!htmlWebpackPlugin.options.skeleton.stylesheet) { %>
|
||||||
|
<link rel="stylesheet" href="../../common/mobile/resources/css/skeleton.css">
|
||||||
|
<% } else { %>
|
||||||
|
<style><%= htmlWebpackPlugin.options.skeleton.stylesheet %></style>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
<!-- built styles file will be auto injected -->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
window.Common = {Locale: {defaultLang: <%= htmlWebpackPlugin.options.system.env.defaultLang %>}};
|
||||||
|
</script>
|
||||||
|
<% if ( htmlWebpackPlugin.options.skeleton.htmlscript ) { %>
|
||||||
|
<script>
|
||||||
|
window.asceditor = 'draw';
|
||||||
|
<%= htmlWebpackPlugin.options.skeleton.htmlscript %>
|
||||||
|
</script>
|
||||||
|
<% } %>
|
||||||
|
<section class="skl-container">
|
||||||
|
<div class="skl-navbar skl-navbar--visio"></div>
|
||||||
|
</section>
|
||||||
|
<script>
|
||||||
|
const isAndroid = /Android/.test(navigator.userAgent);
|
||||||
|
if ( isAndroid && navigator.platform == 'Win32' )
|
||||||
|
// Framework7 doesn't set Device.android flag when navigator.platform == 'Win32', change it for debug
|
||||||
|
navigator.__defineGetter__('platform', () => 'Win32Debug');
|
||||||
|
|
||||||
|
const element_add_class = (el, cls) => (el && el.classList.add(cls));
|
||||||
|
|
||||||
|
let navbar = document.querySelector('.skl-navbar');
|
||||||
|
if ( window.devicePixelRatio ) {
|
||||||
|
element_add_class(navbar, `skl-pixel-ratio--${Math.floor(window.devicePixelRatio)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !isAndroid ) {
|
||||||
|
const ua = navigator.userAgent;
|
||||||
|
const iPad = ua.match(/(iPad).*OS\s([\d_]+)/);
|
||||||
|
const iPhone = !iPad && ua.match(/(iPhone\sOS|iOS)\s([\d_]+)/);
|
||||||
|
|
||||||
|
if ( !iPad && !iPhone ) {
|
||||||
|
Object.defineProperty(navigator, 'userAgent', {
|
||||||
|
get: function () { return `iPad; CPU OS 11_0 ${ua}`; }
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
element_add_class(navbar, `skl-navbar--ios`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
element_add_class(navbar, `skl-navbar--md`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getUrlParams = () => {
|
||||||
|
let e,
|
||||||
|
a = /\+/g, // Regex for replacing addition symbol with a space
|
||||||
|
r = /([^&=]+)=?([^&]*)/g,
|
||||||
|
d = s => decodeURIComponent(s.replace(a, " ")),
|
||||||
|
q = window.location.search.substring(1),
|
||||||
|
urlParams = {};
|
||||||
|
|
||||||
|
while (e = r.exec(q))
|
||||||
|
urlParams[d(e[1])] = d(e[2]);
|
||||||
|
|
||||||
|
return urlParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
let params = getUrlParams();
|
||||||
|
window.frameEditorId = params["frameEditorId"];
|
||||||
|
window.parentOrigin = params["parentOrigin"];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="../../../vendor/jquery/jquery.min.js"></script>
|
||||||
|
|
||||||
|
<div id="app"></div>
|
||||||
|
|
||||||
|
<!-- built script files will be auto injected -->
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
8
apps/visioeditor/mobile/src/less/app-ios.less
Normal file
8
apps/visioeditor/mobile/src/less/app-ios.less
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.device-ios {
|
||||||
|
.view {
|
||||||
|
.page-content{
|
||||||
|
background: @background-tertiary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
24
apps/visioeditor/mobile/src/less/app-material.less
Normal file
24
apps/visioeditor/mobile/src/less/app-material.less
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
// Colors
|
||||||
|
@themeColorLight: #a2bdde;
|
||||||
|
@navBarIconColor: #fff;
|
||||||
|
|
||||||
|
|
||||||
|
.device-android {
|
||||||
|
--f7-navbar-bg-color: @brandColor;
|
||||||
|
--f7-navbar-link-color: @text-link;
|
||||||
|
--f7-navbar-text-color: @text-normal;
|
||||||
|
|
||||||
|
// Main Toolbar
|
||||||
|
#editor-navbar.navbar .right {
|
||||||
|
padding-right: 4px;
|
||||||
|
}
|
||||||
|
#editor-navbar.navbar .right a.link,
|
||||||
|
#editor-navbar.navbar .left a.link {
|
||||||
|
padding: 0 13px;
|
||||||
|
justify-content: space-between;
|
||||||
|
box-sizing: border-box;
|
||||||
|
align-items: center;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
19
apps/visioeditor/mobile/src/less/app-rtl.less
Normal file
19
apps/visioeditor/mobile/src/less/app-rtl.less
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
@import '../../../../common/mobile/resources/less/common-rtl.less';
|
||||||
|
@import '../../../../common/mobile/resources/less/icons.rtl.less';
|
||||||
|
|
||||||
|
[dir="rtl"] {
|
||||||
|
.slide-theme .item-theme.active:before {
|
||||||
|
left: -5px;
|
||||||
|
right: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-layout {
|
||||||
|
.item-inner:before {
|
||||||
|
left: 11px;
|
||||||
|
right: unset;
|
||||||
|
}
|
||||||
|
.row img {
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
118
apps/visioeditor/mobile/src/less/app.less
Normal file
118
apps/visioeditor/mobile/src/less/app.less
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
@import '../../../../../vendor/framework7-react/node_modules/framework7/less/mixins.less';
|
||||||
|
@import '../../../../common/mobile/resources/less/_mixins.less';
|
||||||
|
@import '../../../../common/mobile/resources/less/colors-table.less';
|
||||||
|
@import '../../../../common/mobile/resources/less/colors-table-dark.less';
|
||||||
|
@import './app-rtl.less';
|
||||||
|
|
||||||
|
@brandColor: var(--brand-visio);
|
||||||
|
|
||||||
|
.device-ios {
|
||||||
|
--toolbar-background: var(--background-primary, #fff);
|
||||||
|
--toolbar-segment: var(--brand-visio, #444796);
|
||||||
|
--toolbar-icons: var(--brand-visio, #444796);
|
||||||
|
}
|
||||||
|
.device-android {
|
||||||
|
--toolbar-background: var(--brand-visio, #444796);
|
||||||
|
|
||||||
|
.theme-type-dark {
|
||||||
|
--toolbar-icons: var(--brand-visio, #444796);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@toolbar-background: var(--toolbar-background);
|
||||||
|
@toolbar-segment: var(--toolbar-segment);
|
||||||
|
@button-active-opacity: var(--active-opacity-slide);
|
||||||
|
|
||||||
|
@import '../../../../common/mobile/resources/less/collaboration.less';
|
||||||
|
@import '../../../../common/mobile/resources/less/common.less';
|
||||||
|
@import '../../../../common/mobile/resources/less/common-ios.less';
|
||||||
|
@import '../../../../common/mobile/resources/less/common-material.less';
|
||||||
|
@import '../../../../common/mobile/resources/less/icons.less';
|
||||||
|
@import '../../../../common/mobile/resources/less/about.less';
|
||||||
|
@import '../../../../common/mobile/resources/less/contextmenu.less';
|
||||||
|
@import './app-material.less';
|
||||||
|
@import './app-ios.less';
|
||||||
|
@import './icons-ios.less';
|
||||||
|
@import './icons-material.less';
|
||||||
|
@import './icons-common.less';
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--f7-popover-width: 360px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skeleton of document
|
||||||
|
|
||||||
|
.doc-placeholder {
|
||||||
|
background: var(--canvas-background);
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 6000;
|
||||||
|
position: absolute;
|
||||||
|
padding-top: calc(var(--f7-page-navbar-offset, 0px) + var(--f7-page-subnavbar-offset, 0px));
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.slide-h {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
width: 90%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding-top: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-v {
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
flex-direction: column;
|
||||||
|
padding-bottom: 56.1333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-container {
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
background: var(--canvas-content-background);
|
||||||
|
border: 1px solid var(--canvas-page-border);
|
||||||
|
|
||||||
|
-webkit-animation: flickerAnimation 2s infinite ease-in-out;
|
||||||
|
-moz-animation: flickerAnimation 2s infinite ease-in-out;
|
||||||
|
-o-animation: flickerAnimation 2s infinite ease-in-out;
|
||||||
|
animation: flickerAnimation 2s infinite ease-in-out;
|
||||||
|
|
||||||
|
> .line {
|
||||||
|
height: 20%;
|
||||||
|
margin: 0 120px;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: #f5f5f5;
|
||||||
|
|
||||||
|
&:nth-child(1) {
|
||||||
|
height: 30%;
|
||||||
|
margin: 10% 80px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.empty {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-content {
|
||||||
|
.preview{
|
||||||
|
color: @gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.phone, .tablet {
|
||||||
|
.swiper-container{
|
||||||
|
position: static;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.swiper-pagination-bullet-active{
|
||||||
|
background: @black;
|
||||||
|
}
|
||||||
|
|
||||||
7
apps/visioeditor/mobile/src/less/icons-common.less
Normal file
7
apps/visioeditor/mobile/src/less/icons-common.less
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
i.icon {
|
||||||
|
&.icon-format-vsdx {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
.encoded-svg-background('<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M4 1C2.34315 1 1 2.34315 1 4V20C1 21.6569 2.34315 23 4 23H20C21.6569 23 23 21.6569 23 20V4C23 2.34315 21.6569 1 20 1H4ZM4 6H20V18H4V6ZM5 7H19V17H5V7Z" fill="#BE664F"/></svg>');
|
||||||
|
}
|
||||||
|
}
|
||||||
54
apps/visioeditor/mobile/src/less/icons-ios.less
Normal file
54
apps/visioeditor/mobile/src/less/icons-ios.less
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// Icons
|
||||||
|
.device-ios {
|
||||||
|
i.icon {
|
||||||
|
&.icon-burger {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
.encoded-svg-mask('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 22 22" fill="@{brandColor}"><g><rect x="2" y="17" width="18" height="1"/><rect x="2" y="13" width="18" height="1"/><rect x="2" y="9" width="18" height="1"/><rect x="2" y="5" width="18" height="1"/></g></svg>');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-edit-settings {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
.encoded-svg-mask('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 22 22"><g><path d="M8 1L3 15h1.19995l1.77686-5h5.04638l.61573 1.7325.87988-.87988L9 1zm.5 1.9L10.66772 9H6.33228z" clip-rule="evenodd" fill-rule="evenodd"/><path d="M18.3 11.3l-9.2 9.1-1.5-1.5 9.2-9.1-.7-.7-9.6 9.6L6 22l3.3-.5 9.6-9.6zm1.2 0L21 9.8s-.2-1.2-.9-1.9c-.7-.8-1.9-.9-1.9-.9l-1.5 1.5z"/></g></svg>');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-download {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
.encoded-svg-mask('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 22 22" y="0px" x="0px" fill="@{brandColor}"><path d="M12 0H11L11 14L7.39999 10.3L6.69999 11.1L11.5 16L16.3 11.1L15.6 10.3L12 14L12 0Z"/><path d="M14 5V6H19V20H4V6H9V5H3V21H20V5H14Z"/></svg>');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-print {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
.encoded-svg-mask('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-0 0 22 22" y="0px" x="0px" fill="@{brandColor}"><g><path fill-rule="evenodd" clip-rule="evenodd" d="M5 1H17V6H21V17H17V21H5V17H1V6H5V1ZM6 6H16V2H6V6ZM5 16V13H2V16H5ZM2 12H20V7H2V12ZM20 13H17V16H20V13ZM16 13H6V20H16V13ZM14 16H8V15H14V16ZM14 18H8V17H14V18Z"/></g></svg>');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-feedback {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
.encoded-svg-mask('<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M21 6H3V18H21V6ZM3 5C2.44772 5 2 5.44772 2 6V18C2 18.5523 2.44772 19 3 19H21C21.5523 19 22 18.5523 22 18V6C22 5.44772 21.5523 5 21 5H3Z" fill="black"/><path fill-rule="evenodd" clip-rule="evenodd" d="M2.66552 6.37165L3.33448 5.62835L12 13.3273L20.6655 5.62835L21.3345 6.37165L12 14.6727L2.66552 6.37165Z" fill="black"/><path fill-rule="evenodd" clip-rule="evenodd" d="M9.37629 11.3293L3.37629 18.3293L2.62371 17.6707L8.62371 10.6707L9.37629 11.3293Z" fill="black"/><path fill-rule="evenodd" clip-rule="evenodd" d="M15.3763 10.6707L21.3763 17.6707L20.6237 18.3293L14.6237 11.3293L15.3763 10.6707Z" fill="black"/></svg>');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-setup {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
.encoded-svg-mask('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 22 22" fill="@{brandColor}"><g><path d="M0,3v16h22V3H0z M21,17H1V5h20V17z M16.5,5.9l-7.2,7.2L8.8,15H4v1c0,0,3.2,0,5,0c0.4,0,0.2,0,0.2-0.2l2.2-0.6L18.7,8L16.5,5.9z M9.9,13.1l6.5-6.4L18,8l-6.5,6.4L9.9,13.1z"/></g></svg>');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collaboration
|
||||||
|
|
||||||
|
&.icon-users {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
.encoded-svg-mask('<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M16 7C16 9.34102 15.4162 11.1346 14.6143 12.3121C13.8071 13.4974 12.8337 14 12 14C11.1663 14 10.1929 13.4974 9.38574 12.3121C8.5838 11.1346 8 9.34102 8 7C8 4.61508 9.97853 3 12 3C14.0215 3 16 4.61508 16 7ZM15.1891 13.2201C14.2865 14.375 13.1451 15 12 15C10.8549 15 9.71347 14.375 8.81092 13.2201C7.40473 13.7844 6.21268 14.3488 5.26963 14.9224C3.55256 15.9667 3 16.8326 3 17.5C3 18.2545 3.4257 19.0877 4.82302 19.7879C6.25015 20.5031 8.57272 20.9999 12 21C15.4273 21 17.7499 20.5031 19.177 19.7879C20.5743 19.0877 21 18.2545 21 17.5C21 16.8326 20.4474 15.9667 18.7304 14.9224C17.7873 14.3488 16.5953 13.7844 15.1891 13.2201ZM15.7544 12.37C16.5137 11.0279 17 9.20917 17 7C17 4 14.5088 2 12 2C9.49121 2 7 4 7 7C7 9.20917 7.48633 11.0279 8.24563 12.37C4.38973 13.9392 2 15.579 2 17.5C2 19.9852 5 21.9999 12 22C19 22 22 19.9852 22 17.5C22 15.579 19.6103 13.9392 15.7544 12.37Z" fill="@{brandColor}"/></svg>');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-app-settings {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
.encoded-svg-mask('<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7 14H16C18.2091 14 20 15.7909 20 18C20 20.2091 18.2091 22 16 22H7C4.79086 22 3 20.2091 3 18C3 15.7909 4.79086 14 7 14ZM16 13C18.7614 13 21 15.2386 21 18C21 20.7614 18.7614 23 16 23H7C4.23858 23 2 20.7614 2 18C2 15.2386 4.23858 13 7 13H16Z" fill="@{brandColor}"/><path fill-rule="evenodd" clip-rule="evenodd" d="M16 20C14.8954 20 14 19.1046 14 18C14 16.8954 14.8954 16 16 16C17.1046 16 18 16.8954 18 18C18 19.1046 17.1046 20 16 20ZM16 21C14.3431 21 13 19.6569 13 18C13 16.3431 14.3431 15 16 15C17.6569 15 19 16.3431 19 18C19 19.6569 17.6569 21 16 21Z" fill="@{brandColor}"/><path fill-rule="evenodd" clip-rule="evenodd" d="M16 3H7C4.79086 3 3 4.79086 3 7C3 9.20914 4.79086 11 7 11H16C18.2091 11 20 9.20914 20 7C20 4.79086 18.2091 3 16 3ZM7 2C4.23858 2 2 4.23858 2 7C2 9.76142 4.23858 12 7 12H16C18.7614 12 21 9.76142 21 7C21 4.23858 18.7614 2 16 2H7Z" fill="@{brandColor}"/><path fill-rule="evenodd" clip-rule="evenodd" d="M7 9C8.10457 9 9 8.10457 9 7C9 5.89543 8.10457 5 7 5C5.89543 5 5 5.89543 5 7C5 8.10457 5.89543 9 7 9ZM7 10C8.65685 10 10 8.65685 10 7C10 5.34315 8.65685 4 7 4C5.34315 4 4 5.34315 4 7C4 8.65685 5.34315 10 7 10Z" fill="@{brandColor}"/></svg>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
65
apps/visioeditor/mobile/src/less/icons-material.less
Normal file
65
apps/visioeditor/mobile/src/less/icons-material.less
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// Icons
|
||||||
|
.device-android {
|
||||||
|
i.icon {
|
||||||
|
&.icon-edit-settings {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
.encoded-svg-mask('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 22 22"><g><path d="M2.5 15L8 1h2l4.4146 11.2574-1.6009 1.6008L12.12012 12h-6.25L4.75 15zM9 3.66998L6.62012 10h4.75976z" clip-rule="evenodd" fill-rule="evenodd"/><path d="M10 19.50035V22h2.49965l7.37231-7.37231-2.49965-2.49965zm11.805-6.80572c.26-.25997.26-.67991 0-.93987l-1.5598-1.559787c-.25992-.259964-.67986-.259964-.93983 0L18.08554 11.4148l2.49966 2.49966z"/></g></svg>', @toolbar-icons);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-download {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
.encoded-svg-mask('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 22 22" y="0px" x="0px" fill="@{brandColor}"><path d="M12 0H11L11 14L7.39999 10.3L6.69999 11.1L11.5 16L16.3 11.1L15.6 10.3L12 14L12 0Z"/><path d="M14 5V6H19V20H4V6H9V5H3V21H20V5H14Z"/></svg>');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-print {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
.encoded-svg-mask('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-0 0 22 22" y="0px" x="0px" fill="@{brandColor}"><g><path fill-rule="evenodd" clip-rule="evenodd" d="M5 1H17V6H21V17H17V21H5V17H1V6H5V1ZM6 6H16V2H6V6ZM5 16V13H2V16H5ZM2 12H20V7H2V12ZM20 13H17V16H20V13ZM16 13H6V20H16V13ZM14 16H8V15H14V16ZM14 18H8V17H14V18Z"/></g></svg>');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-feedback {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
.encoded-svg-mask('<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M21 6H3V18H21V6ZM2 5V19H22V5H2Z" fill="black"/><path fill-rule="evenodd" clip-rule="evenodd" d="M2.66552 6.37165L3.33448 5.62835L12 13.3273L20.6655 5.62835L21.3345 6.37165L12 14.6727L2.66552 6.37165Z" fill="black"/><path fill-rule="evenodd" clip-rule="evenodd" d="M9.37629 11.3293L3.37629 18.3293L2.62371 17.6707L8.62371 10.6707L9.37629 11.3293Z" fill="black"/><path fill-rule="evenodd" clip-rule="evenodd" d="M15.3763 10.6707L21.3763 17.6707L20.6237 18.3293L14.6237 11.3293L15.3763 10.6707Z" fill="black"/></svg>');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-setup {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
.encoded-svg-mask('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 22 22" fill="@{brandColor}"><g><path d="M0,3v16h22V3H0z M21,17H1V5h20V17z M16.5,5.9l-7.2,7.2L8.8,15H4v1c0,0,3.2,0,5,0c0.4,0,0.2,0,0.2-0.2l2.2-0.6L18.7,8L16.5,5.9z M9.9,13.1l6.5-6.4L18,8l-6.5,6.4L9.9,13.1z"/></g></svg>');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collaboration
|
||||||
|
|
||||||
|
&.icon-users {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
.encoded-svg-mask('<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M15.5 7C15.5 9.26153 14.9357 10.9518 14.201 12.0307C13.4584 13.121 12.6234 13.5 12 13.5C11.3766 13.5 10.5416 13.121 9.79901 12.0307C9.0643 10.9518 8.5 9.26153 8.5 7C8.5 4.92262 10.2222 3.5 12 3.5C13.7778 3.5 15.5 4.92262 15.5 7ZM14.8461 13.6216C14.006 14.5191 13.0044 15 12 15C10.9956 15 9.99399 14.5191 9.15395 13.6216C7.69714 14.1996 6.4782 14.7725 5.52945 15.3496C3.82884 16.3839 3.5 17.1203 3.5 17.5C3.5 18.0104 3.76355 18.6977 5.04703 19.3409C6.37522 20.0065 8.60909 20.4999 12 20.5C15.3909 20.5 17.6248 20.0065 18.953 19.3409C20.2364 18.6977 20.5 18.0104 20.5 17.5C20.5 17.1203 20.1712 16.3839 18.4705 15.3496C17.5218 14.7725 16.3029 14.1996 14.8461 13.6216ZM15.7544 12.37C16.5137 11.0279 17 9.20917 17 7C17 4 14.5088 2 12 2C9.49121 2 7 4 7 7C7 9.20917 7.48633 11.0279 8.24563 12.37C4.38973 13.9392 2 15.579 2 17.5C2 19.9852 5 21.9999 12 22C19 22 22 19.9852 22 17.5C22 15.579 19.6103 13.9392 15.7544 12.37Z" fill="@{brandColor}"/></svg>');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-app-settings {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
.encoded-svg-mask('<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7 14H16C18.2091 14 20 15.7909 20 18C20 20.2091 18.2091 22 16 22H7C4.79086 22 3 20.2091 3 18C3 15.7909 4.79086 14 7 14ZM16 13C18.7614 13 21 15.2386 21 18C21 20.7614 18.7614 23 16 23H7C4.23858 23 2 20.7614 2 18C2 15.2386 4.23858 13 7 13H16Z" fill="@{brandColor}"/><path fill-rule="evenodd" clip-rule="evenodd" d="M16 20C14.8954 20 14 19.1046 14 18C14 16.8954 14.8954 16 16 16C17.1046 16 18 16.8954 18 18C18 19.1046 17.1046 20 16 20ZM16 21C14.3431 21 13 19.6569 13 18C13 16.3431 14.3431 15 16 15C17.6569 15 19 16.3431 19 18C19 19.6569 17.6569 21 16 21Z" fill="@{brandColor}"/><path fill-rule="evenodd" clip-rule="evenodd" d="M16 3H7C4.79086 3 3 4.79086 3 7C3 9.20914 4.79086 11 7 11H16C18.2091 11 20 9.20914 20 7C20 4.79086 18.2091 3 16 3ZM7 2C4.23858 2 2 4.23858 2 7C2 9.76142 4.23858 12 7 12H16C18.7614 12 21 9.76142 21 7C21 4.23858 18.7614 2 16 2H7Z" fill="@{brandColor}"/><path fill-rule="evenodd" clip-rule="evenodd" d="M7 9C8.10457 9 9 8.10457 9 7C9 5.89543 8.10457 5 7 5C5.89543 5 5 5.89543 5 7C5 8.10457 5.89543 9 7 9ZM7 10C8.65685 10 10 8.65685 10 7C10 5.34315 8.65685 4 7 4C5.34315 4 4 5.34315 4 7C4 8.65685 5.34315 10 7 10Z" fill="@{brandColor}"/></svg>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overwrite color for toolbar
|
||||||
|
.navbar {
|
||||||
|
i.icon {
|
||||||
|
&.icon-logo {
|
||||||
|
width: 100px;
|
||||||
|
height: 14px;
|
||||||
|
//background: url('../../../../common/mobile/resources/img/header/logo-android.svg') no-repeat center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-burger {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
.encoded-svg-mask('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-8 1 22 22" fill="@{toolbar-icons}"><g><path d="M-6,6v2h18V6H-6z M-6,13h18v-2H-6V13z M-6,18h18v-2H-6V18z"/></g></svg>', @toolbar-icons);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
29
apps/visioeditor/mobile/src/lib/i18n.js
Normal file
29
apps/visioeditor/mobile/src/lib/i18n.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import i18n from 'i18next'
|
||||||
|
import {initReactI18next} from 'react-i18next'
|
||||||
|
import Fetch from 'i18next-fetch-backend'
|
||||||
|
|
||||||
|
i18n.use(initReactI18next)
|
||||||
|
.use(Fetch)
|
||||||
|
.init({
|
||||||
|
lng: Common.Locale.currentLang,
|
||||||
|
fallbackLng: Common.Locale.defaultLang,
|
||||||
|
escapeValue: false,
|
||||||
|
backend: {
|
||||||
|
loadPath: './locale/{{lng}}.json'
|
||||||
|
},
|
||||||
|
interpolation: { escapeValue: false },
|
||||||
|
react: {
|
||||||
|
useSuspense: false,
|
||||||
|
},
|
||||||
|
}).then(() => {
|
||||||
|
console.log("i18next is ready");
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("i18next initialization error:", error);
|
||||||
|
});
|
||||||
|
|
||||||
|
i18n.on('failedLoading', (lng, ns, msg) => {
|
||||||
|
console.log(msg);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default i18n;
|
||||||
6
apps/visioeditor/mobile/src/lib/patch.jsx
Normal file
6
apps/visioeditor/mobile/src/lib/patch.jsx
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
const EditorUIController = () => null;
|
||||||
|
|
||||||
|
EditorUIController.isSupportEditFeature = () => false;
|
||||||
|
|
||||||
|
export default EditorUIController;
|
||||||
47
apps/visioeditor/mobile/src/page/app.jsx
Normal file
47
apps/visioeditor/mobile/src/page/app.jsx
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import {App,Panel,Views,View,Popup,Page,Navbar,Toolbar,NavRight,Link,Block,BlockTitle,List,ListItem,ListInput,ListButton,BlockFooter} from 'framework7-react';
|
||||||
|
import { f7ready } from 'framework7-react';
|
||||||
|
|
||||||
|
import '../../../../common/Analytics.js';
|
||||||
|
|
||||||
|
import '../../../../common/Gateway.js';
|
||||||
|
import '../../../../common/main/lib/util/utils.js';
|
||||||
|
|
||||||
|
import routes from '../router/routes.js';
|
||||||
|
|
||||||
|
import Notifications from '../../../../common/mobile/utils/notifications.js'
|
||||||
|
import {MainController} from '../controller/Main';
|
||||||
|
import {Device} from '../../../../common/mobile/utils/device'
|
||||||
|
|
||||||
|
// Framework7 Parameters
|
||||||
|
const f7params = {
|
||||||
|
name: 'Visio Editor', // App name
|
||||||
|
theme: 'auto', // Automatic theme detection
|
||||||
|
|
||||||
|
routes: routes, // App routes
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class extends React.Component {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
Common.Notifications = new Notifications();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<App { ...f7params } className={'app-layout'}>
|
||||||
|
{/* Your main view, should have "view-main" class */}
|
||||||
|
<View main className="safe-areas" url="/" />
|
||||||
|
<MainController />
|
||||||
|
</App>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
f7ready(f7 => {
|
||||||
|
Device.initDom();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
205
apps/visioeditor/mobile/src/page/main.jsx
Normal file
205
apps/visioeditor/mobile/src/page/main.jsx
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
import React, { Component, createContext } from 'react';
|
||||||
|
import { f7, Page, View, Navbar, Subnavbar, Icon } from 'framework7-react';
|
||||||
|
import { observer, inject } from "mobx-react";
|
||||||
|
import { Device } from '../../../../common/mobile/utils/device';
|
||||||
|
import CollaborationView from '../../../../common/mobile/lib/view/collaboration/Collaboration.jsx';
|
||||||
|
import ContextMenu from '../controller/ContextMenu';
|
||||||
|
import { Toolbar } from "../controller/Toolbar";
|
||||||
|
import { Themes } from '../../../../common/mobile/lib/controller/Themes';
|
||||||
|
import SettingsController from '../controller/settings/Settings';
|
||||||
|
|
||||||
|
export const MainContext = createContext();
|
||||||
|
|
||||||
|
class MainPage extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
settingsVisible: false,
|
||||||
|
collaborationVisible: false,
|
||||||
|
isOpenModal: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
onClosePreview = () => {
|
||||||
|
this.setState({previewVisible: false});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClickToOpenOptions = (opts, showOpts) => {
|
||||||
|
f7.popover.close('.document-menu.modal-in', false);
|
||||||
|
|
||||||
|
let opened = false;
|
||||||
|
const newState = {};
|
||||||
|
|
||||||
|
if ( opts === 'settings' ) {
|
||||||
|
this.state.settingsVisible && (opened = true);
|
||||||
|
newState.settingsVisible = true;
|
||||||
|
newState.isOpenModal = true;
|
||||||
|
} else if ( opts === 'coauth' ) {
|
||||||
|
this.state.collaborationVisible && (opened = true);
|
||||||
|
newState.collaborationVisible = true;
|
||||||
|
newState.isOpenModal = true;
|
||||||
|
}
|
||||||
|
for (let key in this.state) {
|
||||||
|
if (this.state[key] && !opened) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.handleClickToOpenOptions(opts, showOpts);
|
||||||
|
}, 10);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!opened) {
|
||||||
|
this.setState(newState);
|
||||||
|
if ((opts === 'edit' || opts === 'coauth') && Device.phone) {
|
||||||
|
f7.navbar.hide('.main-navbar');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
handleOptionsViewClosed = opts => {
|
||||||
|
this.setState(state => {
|
||||||
|
if ( opts == 'settings' )
|
||||||
|
return {settingsVisible: false, isOpenModal: false};
|
||||||
|
else if ( opts == 'coauth' )
|
||||||
|
return {collaborationVisible: false, isOpenModal: false}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ((opts === 'edit' || opts === 'coauth') && Device.phone) {
|
||||||
|
f7.navbar.show('.main-navbar');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
touchMoveHandler (e) {
|
||||||
|
if (e.touches.length > 1 && !e.target.closest('#editor_sdk')) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gesturePreventHandler (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount () {
|
||||||
|
if ($$('.skl-container').length) {
|
||||||
|
$$('.skl-container').remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
document.addEventListener('touchmove', this.touchMoveHandler);
|
||||||
|
|
||||||
|
if (Device.ios) {
|
||||||
|
document.addEventListener('gesturestart', this.gesturePreventHandler);
|
||||||
|
document.addEventListener('gesturechange', this.gesturePreventHandler);
|
||||||
|
document.addEventListener('gestureend', this.gesturePreventHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
document.removeEventListener('touchmove', this.touchMoveHandler);
|
||||||
|
|
||||||
|
if (Device.ios) {
|
||||||
|
document.removeEventListener('gesturestart', this.gesturePreventHandler);
|
||||||
|
document.removeEventListener('gesturechange', this.gesturePreventHandler);
|
||||||
|
document.removeEventListener('gestureend', this.gesturePreventHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const appOptions = this.props.storeAppOptions;
|
||||||
|
const storeThemes = this.props.storeThemes;
|
||||||
|
const colorTheme = storeThemes.colorTheme;
|
||||||
|
const config = appOptions.config;
|
||||||
|
const { customization = {} } = config;
|
||||||
|
const isShowPlaceholder = !appOptions.isDocReady && (!customization || !(customization.loaderName || customization.loaderLogo));
|
||||||
|
|
||||||
|
let isBranding = true,
|
||||||
|
isHideLogo = true,
|
||||||
|
customLogoImage = '',
|
||||||
|
customLogoUrl = '';
|
||||||
|
|
||||||
|
if(!appOptions.isDisconnected && appOptions.isDocReady) {
|
||||||
|
const { logo } = customization;
|
||||||
|
isBranding = appOptions.canBranding || appOptions.canBrandingExt;
|
||||||
|
|
||||||
|
if(logo && isBranding) {
|
||||||
|
isHideLogo = logo.visible === false;
|
||||||
|
|
||||||
|
if(logo.image || logo.imageDark || logo.imageLight) {
|
||||||
|
customLogoImage = colorTheme.type === 'dark' ? logo.imageDark ?? logo.image ?? logo.imageLight : logo.imageLight ?? logo.image ?? logo.imageDark;
|
||||||
|
customLogoUrl = logo.url;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
isHideLogo = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Themes>
|
||||||
|
<MainContext.Provider value={{
|
||||||
|
openOptions: this.handleClickToOpenOptions.bind(this),
|
||||||
|
closeOptions: this.handleOptionsViewClosed.bind(this),
|
||||||
|
showPanels: this.state.addShowOptions,
|
||||||
|
isBranding
|
||||||
|
}}>
|
||||||
|
{!this.state.previewVisible ? null :
|
||||||
|
<Preview closeOptions={this.handleOptionsViewClosed.bind(this)} />
|
||||||
|
}
|
||||||
|
<Page name="home" className={`editor${!isHideLogo ? ' page-with-logo' : ''}`}>
|
||||||
|
{/* Top Navbar */}
|
||||||
|
<Navbar id='editor-navbar' className={`main-navbar${!isHideLogo ? ' navbar-with-logo' : ''}`}>
|
||||||
|
{!isHideLogo &&
|
||||||
|
<div className="main-logo" onClick={() => {
|
||||||
|
window.open(`${customLogoImage && customLogoUrl ? customLogoUrl : __PUBLISHER_URL__}`, "_blank");
|
||||||
|
}}>
|
||||||
|
{customLogoImage ?
|
||||||
|
<img className='custom-logo-image' src={customLogoImage} />
|
||||||
|
:
|
||||||
|
<Icon icon="icon-logo"></Icon>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<Subnavbar>
|
||||||
|
<Toolbar
|
||||||
|
openOptions={this.handleClickToOpenOptions}
|
||||||
|
closeOptions={this.handleOptionsViewClosed}
|
||||||
|
isOpenModal={this.state.isOpenModal}
|
||||||
|
/>
|
||||||
|
</Subnavbar>
|
||||||
|
</Navbar>
|
||||||
|
{/* Page content */}
|
||||||
|
<View id="editor_sdk" />
|
||||||
|
|
||||||
|
{isShowPlaceholder ?
|
||||||
|
<div className="doc-placeholder">
|
||||||
|
<div className="slide-h">
|
||||||
|
<div className="slide-v">
|
||||||
|
<div className="slide-container">
|
||||||
|
<div className="line"></div>
|
||||||
|
<div className="line empty"></div>
|
||||||
|
<div className="line"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> :
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
{!this.state.settingsVisible ? null : <SettingsController />}
|
||||||
|
{!this.state.collaborationVisible ? null :
|
||||||
|
<CollaborationView
|
||||||
|
closeOptions={this.handleOptionsViewClosed.bind(this)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
{appOptions.isDocReady &&
|
||||||
|
<ContextMenu
|
||||||
|
openOptions={this.handleClickToOpenOptions.bind(this)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</Page>
|
||||||
|
</MainContext.Provider>
|
||||||
|
</Themes>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default inject('storeAppOptions', 'storeThemes')(observer(MainPage));
|
||||||
11
apps/visioeditor/mobile/src/router/routes.js
Normal file
11
apps/visioeditor/mobile/src/router/routes.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
import MainPage from '../page/main';
|
||||||
|
|
||||||
|
var routes = [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
component: MainPage,
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export default routes;
|
||||||
157
apps/visioeditor/mobile/src/store/appOptions.js
Normal file
157
apps/visioeditor/mobile/src/store/appOptions.js
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
import {action, observable, makeObservable} from 'mobx';
|
||||||
|
import { LocalStorage } from '../../../../common/mobile/utils/LocalStorage.mjs';
|
||||||
|
|
||||||
|
export class storeAppOptions {
|
||||||
|
constructor() {
|
||||||
|
makeObservable(this, {
|
||||||
|
isEdit: observable,
|
||||||
|
canViewComments: observable,
|
||||||
|
setConfigOptions: action,
|
||||||
|
setPermissionOptions: action,
|
||||||
|
|
||||||
|
lostEditingRights: observable,
|
||||||
|
changeEditingRights: action,
|
||||||
|
canBrandingExt: observable,
|
||||||
|
canBranding: observable,
|
||||||
|
|
||||||
|
isDocReady: observable,
|
||||||
|
changeDocReady: action,
|
||||||
|
|
||||||
|
customization: observable,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
isEdit = false;
|
||||||
|
canViewComments = false;
|
||||||
|
canBrandingExt = true;
|
||||||
|
canBranding = true;
|
||||||
|
config = {};
|
||||||
|
customization;
|
||||||
|
|
||||||
|
lostEditingRights = false;
|
||||||
|
changeEditingRights (value) {
|
||||||
|
this.lostEditingRights = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
isDocReady = false;
|
||||||
|
changeDocReady (value) {
|
||||||
|
this.isDocReady = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
setConfigOptions (config, _t) {
|
||||||
|
this.config = config;
|
||||||
|
this.customization = config.customization;
|
||||||
|
this.canRenameAnonymous = !((typeof (this.customization) == 'object') && (typeof (this.customization.anonymous) == 'object') && (this.customization.anonymous.request===false));
|
||||||
|
this.guestName = (typeof (this.customization) == 'object') && (typeof (this.customization.anonymous) == 'object') &&
|
||||||
|
(typeof (this.customization.anonymous.label) == 'string') && this.customization.anonymous.label.trim()!=='' ?
|
||||||
|
Common.Utils.String.htmlEncode(this.customization.anonymous.label) : _t.textGuest;
|
||||||
|
|
||||||
|
const value = this.canRenameAnonymous ? LocalStorage.getItem("guest-username") : null;
|
||||||
|
this.canRename = this.config.canRename;
|
||||||
|
this.user = Common.Utils.fillUserInfo(config.user, config.lang, value ? (value + ' (' + this.guestName + ')' ) : _t.textAnonymous, LocalStorage.getItem("guest-id") || ('uid-' + Date.now()));
|
||||||
|
this.user.anonymous && LocalStorage.setItem("guest-id", this.user.id);
|
||||||
|
|
||||||
|
config.user = this.user;
|
||||||
|
this.isDesktopApp = config.targetApp == 'desktop';
|
||||||
|
this.canCreateNew = !!config.createUrl && !this.isDesktopApp;
|
||||||
|
this.canOpenRecent = config.recent !== undefined && !this.isDesktopApp;
|
||||||
|
this.templates = config.templates;
|
||||||
|
this.recent = config.recent;
|
||||||
|
this.createUrl = config.createUrl;
|
||||||
|
this.lang = config.lang;
|
||||||
|
this.location = (typeof (config.location) == 'string') ? config.location.toLowerCase() : '';
|
||||||
|
this.region = (typeof (config.region) == 'string') ? config.region.toLowerCase() : config.region;
|
||||||
|
this.sharingSettingsUrl = config.sharingSettingsUrl;
|
||||||
|
this.fileChoiceUrl = config.fileChoiceUrl;
|
||||||
|
this.mergeFolderUrl = config.mergeFolderUrl;
|
||||||
|
this.canAnalytics = false;
|
||||||
|
this.canRequestClose = config.canRequestClose;
|
||||||
|
this.canCloseEditor = false;
|
||||||
|
|
||||||
|
let canBack = false;
|
||||||
|
|
||||||
|
if (typeof config.customization === 'object' && config.customization !== null) {
|
||||||
|
const { goback, close } = config.customization;
|
||||||
|
|
||||||
|
if (typeof goback === 'object' && config.canBackToFolder !== false) {
|
||||||
|
const hasUrl = !!goback.url;
|
||||||
|
const requestClose = goback.requestClose && this.canRequestClose;
|
||||||
|
|
||||||
|
canBack = close === undefined ? hasUrl || requestClose : hasUrl && !goback.requestClose;
|
||||||
|
|
||||||
|
if (goback.requestClose) {
|
||||||
|
console.log("Obsolete: The 'requestClose' parameter of the 'customization.goback' section is deprecated. Please use 'close' parameter in the 'customization' section instead.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof close === 'object' && close !== null) {
|
||||||
|
this.canCloseEditor = (close.visible!==false) && this.canRequestClose && !this.isDesktopApp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.canBack = this.canBackToFolder = canBack;
|
||||||
|
this.canPlugins = false;
|
||||||
|
|
||||||
|
AscCommon.UserInfoParser.setParser(true);
|
||||||
|
AscCommon.UserInfoParser.setCurrentName(this.user.fullname);
|
||||||
|
}
|
||||||
|
|
||||||
|
setPermissionOptions (document, licType, params, permissions, isSupportEditFeature) {
|
||||||
|
if (params.asc_getRights() !== Asc.c_oRights.Edit)
|
||||||
|
permissions.edit = false;
|
||||||
|
this.review = (permissions.review === undefined) ? (permissions.edit !== false) : permissions.review;
|
||||||
|
this.canAnalytics = params.asc_getIsAnalyticsEnable();
|
||||||
|
this.canLicense = (licType === Asc.c_oLicenseResult.Success || licType === Asc.c_oLicenseResult.SuccessLimit);
|
||||||
|
this.isLightVersion = params.asc_getIsLight();
|
||||||
|
this.buildVersion = params.asc_getBuildVersion();
|
||||||
|
this.canCoAuthoring = !this.isLightVersion;
|
||||||
|
this.isOffline = Common.EditorApi.get().asc_isOffline();
|
||||||
|
this.isReviewOnly = (permissions.review === true) && (permissions.edit === false);
|
||||||
|
this.canRequestEditRights = this.config.canRequestEditRights;
|
||||||
|
this.canEdit = (permissions.edit !== false || permissions.review === true) && // can edit or review
|
||||||
|
(this.config.canRequestEditRights || this.config.mode !== 'view') && // if mode=="view" -> canRequestEditRights must be defined
|
||||||
|
(!this.isReviewOnly || this.canLicense) && // if isReviewOnly==true -> canLicense must be true
|
||||||
|
isSupportEditFeature;
|
||||||
|
this.isEdit = this.canLicense && this.canEdit && this.config.mode !== 'view';
|
||||||
|
this.canReview = this.canLicense && this.isEdit && (permissions.review===true);
|
||||||
|
this.canUseHistory = this.canLicense && this.config.canUseHistory && this.canCoAuthoring && !this.isDesktopApp && !this.isOffline;
|
||||||
|
this.canHistoryClose = this.config.canHistoryClose;
|
||||||
|
this.canHistoryRestore= this.config.canHistoryRestore;
|
||||||
|
this.canUseMailMerge = this.canLicense && this.canEdit && !this.isDesktopApp;
|
||||||
|
this.canSendEmailAddresses = this.canLicense && this.config.canSendEmailAddresses && this.canEdit && this.canCoAuthoring;
|
||||||
|
this.canComments = this.canLicense && (permissions.comment === undefined ? this.isEdit : permissions.comment) && (this.config.mode !== 'view');
|
||||||
|
this.canComments = this.canComments && !((typeof (this.customization) == 'object') && this.customization.comments===false);
|
||||||
|
this.canViewComments = this.canComments || !((typeof (this.customization) == 'object') && this.customization.comments===false);
|
||||||
|
this.canEditComments = this.isOffline || !permissions.editCommentAuthorOnly;
|
||||||
|
this.canDeleteComments= this.isOffline || !permissions.deleteCommentAuthorOnly;
|
||||||
|
if ((typeof (this.customization) == 'object') && this.customization.commentAuthorOnly===true) {
|
||||||
|
console.log("Obsolete: The 'commentAuthorOnly' parameter of the 'customization' section is deprecated. Please use 'editCommentAuthorOnly' and 'deleteCommentAuthorOnly' parameters in the permissions instead.");
|
||||||
|
if (permissions.editCommentAuthorOnly===undefined && permissions.deleteCommentAuthorOnly===undefined)
|
||||||
|
this.canEditComments = this.canDeleteComments = this.isOffline;
|
||||||
|
}
|
||||||
|
// this.isForm = !!window.isPDFForm;
|
||||||
|
this.canChat = this.canLicense && !this.isOffline && (permissions.chat !== false);
|
||||||
|
this.canEditStyles = this.canLicense && this.canEdit;
|
||||||
|
this.canPrint = (permissions.print !== false);
|
||||||
|
this.isRestrictedEdit = !this.isEdit && this.canComments && isSupportEditFeature;
|
||||||
|
this.trialMode = params.asc_getLicenseMode();
|
||||||
|
|
||||||
|
const type = /^(?:(pdf|djvu|xps|oxps))$/.exec(document.fileType);
|
||||||
|
this.canDownloadOrigin = permissions.download !== false && (type && typeof type[1] === 'string');
|
||||||
|
this.canDownload = permissions.download !== false && (!type || typeof type[1] !== 'string');
|
||||||
|
|
||||||
|
this.canBranding = params.asc_getCustomization();
|
||||||
|
this.canBrandingExt = params.asc_getCanBranding() && (typeof this.customization == 'object' || this.config.plugins);
|
||||||
|
|
||||||
|
this.canUseReviewPermissions = this.canLicense && (!!permissions.reviewGroups || this.customization
|
||||||
|
&& this.customization.reviewPermissions && (typeof (this.customization.reviewPermissions) == 'object'));
|
||||||
|
this.canUseCommentPermissions = this.canLicense && !!permissions.commentGroups;
|
||||||
|
this.canUseUserInfoPermissions = this.canLicense && !!permissions.userInfoGroups;
|
||||||
|
this.canUseReviewPermissions && AscCommon.UserInfoParser.setReviewPermissions(permissions.reviewGroups, this.customization.reviewPermissions);
|
||||||
|
this.canUseCommentPermissions && AscCommon.UserInfoParser.setCommentPermissions(permissions.commentGroups);
|
||||||
|
this.canUseUserInfoPermissions && AscCommon.UserInfoParser.setUserInfoPermissions(permissions.userInfoGroups);
|
||||||
|
|
||||||
|
this.canLiveView = !!params.asc_getLiveViewerSupport() && (this.config.mode === 'view') && isSupportEditFeature;
|
||||||
|
this.isAnonymousSupport = !!Common.EditorApi.get().asc_isAnonymousSupport();
|
||||||
|
}
|
||||||
|
}
|
||||||
24
apps/visioeditor/mobile/src/store/applicationSettings.js
Normal file
24
apps/visioeditor/mobile/src/store/applicationSettings.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import {action, observable, makeObservable} from 'mobx';
|
||||||
|
import { LocalStorage } from '../../../../common/mobile/utils/LocalStorage.mjs';
|
||||||
|
|
||||||
|
export class storeApplicationSettings {
|
||||||
|
constructor() {
|
||||||
|
makeObservable(this, {
|
||||||
|
// macrosMode: observable,
|
||||||
|
// macrosRequest: observable,
|
||||||
|
// changeMacrosSettings: action,
|
||||||
|
// changeMacrosRequest: action,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// macrosMode = 0;
|
||||||
|
// macrosRequest = 0;
|
||||||
|
|
||||||
|
// changeMacrosSettings(value) {
|
||||||
|
// this.macrosMode = +value;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// changeMacrosRequest(value) {
|
||||||
|
// this.macrosRequest = value;
|
||||||
|
// }
|
||||||
|
}
|
||||||
17
apps/visioeditor/mobile/src/store/mainStore.js
Normal file
17
apps/visioeditor/mobile/src/store/mainStore.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
import {storeAppOptions} from './appOptions';
|
||||||
|
import {storeUsers} from '../../../../common/mobile/lib/store/users';
|
||||||
|
import {storeApplicationSettings} from './applicationSettings';
|
||||||
|
import {storeVisioInfo} from './visioInfo';
|
||||||
|
import {storeToolbarSettings} from "./toolbar";
|
||||||
|
import { storeThemes } from '../../../../common/mobile/lib/store/themes';
|
||||||
|
|
||||||
|
export const stores = {
|
||||||
|
storeAppOptions: new storeAppOptions(),
|
||||||
|
users: new storeUsers(),
|
||||||
|
storeApplicationSettings: new storeApplicationSettings(),
|
||||||
|
storeVisioInfo: new storeVisioInfo(),
|
||||||
|
storeToolbarSettings: new storeToolbarSettings(),
|
||||||
|
storeThemes: new storeThemes()
|
||||||
|
};
|
||||||
|
|
||||||
32
apps/visioeditor/mobile/src/store/toolbar.js
Normal file
32
apps/visioeditor/mobile/src/store/toolbar.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import {action, observable, makeObservable} from 'mobx';
|
||||||
|
|
||||||
|
export class storeToolbarSettings {
|
||||||
|
constructor() {
|
||||||
|
makeObservable(this, {
|
||||||
|
countPages: observable,
|
||||||
|
setCountPages: action,
|
||||||
|
disabledControls: observable,
|
||||||
|
setDisabledControls: action,
|
||||||
|
disabledSettings: observable,
|
||||||
|
setDisabledSettings: action
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
disabledControls = true;
|
||||||
|
|
||||||
|
setDisabledControls(value) {
|
||||||
|
this.disabledControls = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
disabledSettings = false;
|
||||||
|
|
||||||
|
setDisabledSettings(value) {
|
||||||
|
this.disabledSettings = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
countPages = 0;
|
||||||
|
|
||||||
|
setCountPages(count) {
|
||||||
|
this.countPages = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
21
apps/visioeditor/mobile/src/store/visioInfo.js
Normal file
21
apps/visioeditor/mobile/src/store/visioInfo.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { action, observable, makeObservable } from "mobx";
|
||||||
|
|
||||||
|
export class storeVisioInfo {
|
||||||
|
constructor() {
|
||||||
|
makeObservable(this, {
|
||||||
|
dataDoc: observable,
|
||||||
|
setDataDoc: action,
|
||||||
|
changeTitle: action
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
dataDoc;
|
||||||
|
|
||||||
|
setDataDoc(obj) {
|
||||||
|
this.dataDoc = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
changeTitle(title) {
|
||||||
|
this.dataDoc.title = title;
|
||||||
|
}
|
||||||
|
}
|
||||||
29
apps/visioeditor/mobile/src/view/Toolbar.jsx
Normal file
29
apps/visioeditor/mobile/src/view/Toolbar.jsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import React, {Fragment} from 'react';
|
||||||
|
import {NavLeft, NavRight, Link} from 'framework7-react';
|
||||||
|
import { Device } from '../../../../common/mobile/utils/device';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
const ToolbarView = props => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const isDisconnected = props.isDisconnected;
|
||||||
|
const docTitle = props.docTitle;
|
||||||
|
const isOpenModal = props.isOpenModal;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<NavLeft>
|
||||||
|
{(props.isShowBack) && <Link className={`btn-doc-back${(props.disabledControls || isOpenModal) && ' disabled'}`} icon='icon-return' onClick={() => Common.Notifications.trigger('goback')}></Link>}
|
||||||
|
</NavLeft>
|
||||||
|
{(!Device.phone) &&
|
||||||
|
<div className='title' onClick={() => props.changeTitleHandler()} style={{width: '71%'}}>
|
||||||
|
{docTitle}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<NavRight>
|
||||||
|
<Link className={(props.disabledSettings || props.disabledControls || isDisconnected || isOpenModal) && 'disabled'} id='btn-settings' icon='icon-settings' href={false} onClick={() => props.openOptions('settings')}></Link>
|
||||||
|
</NavRight>
|
||||||
|
</Fragment>
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ToolbarView;
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
import React, { Fragment } from "react";
|
||||||
|
import { observer, inject } from "mobx-react";
|
||||||
|
import { Page, Navbar, List, ListItem, BlockTitle, Toggle, Block } from "framework7-react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
const PageApplicationSettings = props => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const _t = t("View.Settings", { returnObjects: true });
|
||||||
|
const storeApplicationSettings = props.storeApplicationSettings;
|
||||||
|
const unitMeasurement = storeApplicationSettings.unitMeasurement;
|
||||||
|
|
||||||
|
// set mode
|
||||||
|
const appOptions = props.storeAppOptions;
|
||||||
|
const storeThemes = props.storeThemes;
|
||||||
|
const colorTheme = storeThemes.colorTheme;
|
||||||
|
const themes = storeThemes.themes;
|
||||||
|
const typeTheme = colorTheme.type;
|
||||||
|
const isConfigSelectTheme = storeThemes.isConfigSelectTheme;
|
||||||
|
// const _isShowMacros = (!appOptions.isDisconnected && appOptions.customization) ? appOptions.customization.macros !== false : true;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Page>
|
||||||
|
<Navbar title={_t.textApplicationSettings} backLink={_t.textBack} />
|
||||||
|
{!!isConfigSelectTheme &&
|
||||||
|
<List mediaList>
|
||||||
|
<ListItem title={t("Common.Themes.textTheme")} after={themes[typeTheme].text} link="/theme-settings/" routeProps={{
|
||||||
|
changeTheme: props.changeTheme,
|
||||||
|
}}></ListItem>
|
||||||
|
</List>
|
||||||
|
}
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const PageThemeSettings = props => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const _t = t("View.Settings", { returnObjects: true });
|
||||||
|
const storeThemes = props.storeThemes;
|
||||||
|
const colorTheme = storeThemes.colorTheme;
|
||||||
|
const typeTheme = colorTheme.type;
|
||||||
|
const themes = storeThemes.themes;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Page>
|
||||||
|
<Navbar title={t('Common.Themes.textTheme')} backLink={_t.textBack} />
|
||||||
|
<List>
|
||||||
|
{Object.keys(themes).map((key, index) => {
|
||||||
|
return (
|
||||||
|
<ListItem key={index} radio checked={typeTheme === themes[key].type} onChange={() => props.changeTheme(key)} name={themes[key].id} title={themes[key].text}></ListItem>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</List>
|
||||||
|
</Page>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const ApplicationSettings = inject("storeApplicationSettings", "storeAppOptions", "storeThemes")(observer(PageApplicationSettings));
|
||||||
|
const ThemeSettings = inject("storeThemes")(observer(PageThemeSettings));
|
||||||
|
// const MacrosSettings = inject("storeApplicationSettings")(observer(PageMacrosSettings));
|
||||||
|
|
||||||
|
export {ApplicationSettings, ThemeSettings};
|
||||||
28
apps/visioeditor/mobile/src/view/settings/Download.jsx
Normal file
28
apps/visioeditor/mobile/src/view/settings/Download.jsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Page, Navbar, List, ListItem, BlockTitle, Icon } from "framework7-react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
const Download = props => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const _t = t("View.Settings", { returnObjects: true });
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Page>
|
||||||
|
<Navbar title={_t.textDownload} backLink={_t.textBack} />
|
||||||
|
<BlockTitle>{_t.textDownloadAs}</BlockTitle>
|
||||||
|
<List>
|
||||||
|
<ListItem title="VSDX" onClick={() => props.onSaveFormat(Asc.c_oAscFileType.VSDX)}>
|
||||||
|
<Icon slot="media" icon="icon-format-vsdx"></Icon>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem title="PDF" onClick={() => props.onSaveFormat(Asc.c_oAscFileType.PDF)}>
|
||||||
|
<Icon slot="media" icon="icon-format-pdf"></Icon>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem title="PDF/A" onClick={() => props.onSaveFormat(Asc.c_oAscFileType.PDFA)}>
|
||||||
|
<Icon slot="media" icon="icon-format-pdfa"></Icon>
|
||||||
|
</ListItem>
|
||||||
|
</List>
|
||||||
|
</Page>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Download;
|
||||||
73
apps/visioeditor/mobile/src/view/settings/Settings.jsx
Normal file
73
apps/visioeditor/mobile/src/view/settings/Settings.jsx
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import React, { useContext, useEffect } from 'react';
|
||||||
|
import { View, Popup, Popover, f7 } from 'framework7-react';
|
||||||
|
import { Device } from '../../../../../common/mobile/utils/device';
|
||||||
|
import ApplicationSettingsController from "../../controller/settings/ApplicationSettings";
|
||||||
|
import { ThemeSettings } from "./ApplicationSettings";
|
||||||
|
import DownloadController from "../../controller/settings/Download";
|
||||||
|
import VisioInfoController from "../../controller/settings/VisioInfo";
|
||||||
|
import About from '../../../../../common/mobile/lib/view/About';
|
||||||
|
import SettingsPage from './SettingsPage';
|
||||||
|
import { MainContext } from '../../page/main';
|
||||||
|
|
||||||
|
const routes = [
|
||||||
|
{
|
||||||
|
path: '/settings-page/',
|
||||||
|
component: SettingsPage,
|
||||||
|
keepAlive: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/application-settings/',
|
||||||
|
component: ApplicationSettingsController
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/theme-settings/',
|
||||||
|
component: ThemeSettings
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/download/',
|
||||||
|
component: DownloadController
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/visio-info/',
|
||||||
|
component: VisioInfoController
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/about/',
|
||||||
|
component: About
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
routes.forEach(route => {
|
||||||
|
route.options = {
|
||||||
|
...route.options,
|
||||||
|
transition: 'f7-push'
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const SettingsView = () => {
|
||||||
|
const mainContext = useContext(MainContext);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if(Device.phone) {
|
||||||
|
f7.popup.open('.settings-popup');
|
||||||
|
} else {
|
||||||
|
f7.popover.open('#settings-popover', '#btn-settings');
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
!Device.phone ?
|
||||||
|
<Popover id="settings-popover" closeByOutsideClick={false} className="popover__titled" onPopoverClosed={() => mainContext.closeOptions('settings')}>
|
||||||
|
<View style={{ height: '410px' }} routes={routes} url='/settings-page/'>
|
||||||
|
<SettingsPage />
|
||||||
|
</View>
|
||||||
|
</Popover> :
|
||||||
|
<Popup className="settings-popup" onPopupClosed={() => mainContext.closeOptions('settings')}>
|
||||||
|
<View routes={routes} url='/settings-page/'>
|
||||||
|
<SettingsPage />
|
||||||
|
</View>
|
||||||
|
</Popup>
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SettingsView;
|
||||||
107
apps/visioeditor/mobile/src/view/settings/SettingsPage.jsx
Normal file
107
apps/visioeditor/mobile/src/view/settings/SettingsPage.jsx
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
import React, { useContext } from 'react';
|
||||||
|
import { Page, Navbar, NavRight, Link, Icon, ListItem, List, f7 } from 'framework7-react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { Device } from '../../../../../common/mobile/utils/device';
|
||||||
|
import { observer, inject } from "mobx-react";
|
||||||
|
import { MainContext } from '../../page/main';
|
||||||
|
import { SettingsContext } from '../../controller/settings/Settings';
|
||||||
|
|
||||||
|
const SettingsPage = inject('storeAppOptions', 'storeVisioInfo')(observer(props => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const _t = t('View.Settings', {returnObjects: true});
|
||||||
|
const {openOptions, isBranding} = useContext(MainContext);
|
||||||
|
const settingsContext = useContext(SettingsContext);
|
||||||
|
const appOptions = props.storeAppOptions;
|
||||||
|
const storeVisioInfo = props.storeVisioInfo;
|
||||||
|
const docTitle = storeVisioInfo.dataDoc ? storeVisioInfo.dataDoc.title : '';
|
||||||
|
const canCloseEditor = appOptions.canCloseEditor;
|
||||||
|
const closeButtonText = canCloseEditor && appOptions.customization.close.text;
|
||||||
|
const navbar =
|
||||||
|
<Navbar>
|
||||||
|
<div className="title" onClick={settingsContext.changeTitleHandler}>{docTitle}</div>
|
||||||
|
{Device.phone && <NavRight><Link popupClose=".settings-popup">{_t.textDone}</Link></NavRight>}
|
||||||
|
</Navbar>;
|
||||||
|
|
||||||
|
const onOpenOptions = name => {
|
||||||
|
settingsContext.closeModal();
|
||||||
|
openOptions(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
let _canDownload = false,
|
||||||
|
_canDownloadOrigin = false,
|
||||||
|
_canAbout = true,
|
||||||
|
_canHelp = true,
|
||||||
|
_canPrint = false,
|
||||||
|
_canFeedback = true,
|
||||||
|
_canDisplayInfo = true;
|
||||||
|
|
||||||
|
if (appOptions.isDisconnected) {
|
||||||
|
if (!appOptions.enableDownload)
|
||||||
|
_canPrint = _canDownload = _canDownloadOrigin = false;
|
||||||
|
} else {
|
||||||
|
_canDownload = appOptions.canDownload;
|
||||||
|
_canDownloadOrigin = appOptions.canDownloadOrigin;
|
||||||
|
_canPrint = appOptions.canPrint;
|
||||||
|
|
||||||
|
if (appOptions.customization && appOptions.canBrandingExt) {
|
||||||
|
_canAbout = appOptions.customization.about !== false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (appOptions.customization) {
|
||||||
|
_canHelp = appOptions.customization.help !== false;
|
||||||
|
_canFeedback = appOptions.customization.feedback !== false;
|
||||||
|
_canDisplayInfo = appOptions.customization.mobile?.info !== false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Page>
|
||||||
|
{navbar}
|
||||||
|
<List>
|
||||||
|
<ListItem title={_t.textApplicationSettings} link="/application-settings/">
|
||||||
|
<Icon slot="media" icon="icon-app-settings"></Icon>
|
||||||
|
</ListItem>
|
||||||
|
{_canDownload &&
|
||||||
|
<ListItem title={_t.textDownload} link="/download/">
|
||||||
|
<Icon slot="media" icon="icon-download"></Icon>
|
||||||
|
</ListItem>
|
||||||
|
}
|
||||||
|
{_canDownloadOrigin &&
|
||||||
|
<ListItem title={_t.textDownload} link="#" onClick={settingsContext.onDownloadOrigin} className='no-indicator'>
|
||||||
|
<Icon slot="media" icon="icon-download"></Icon>
|
||||||
|
</ListItem>
|
||||||
|
}
|
||||||
|
{_canPrint &&
|
||||||
|
<ListItem title={_t.textPrint} onClick={settingsContext.onPrint}>
|
||||||
|
<Icon slot="media" icon="icon-print"></Icon>
|
||||||
|
</ListItem>
|
||||||
|
}
|
||||||
|
{!(!_canDisplayInfo && isBranding) &&
|
||||||
|
<ListItem title={_t.textVisioInfo} link="/visio-info/">
|
||||||
|
<Icon slot="media" icon="icon-info"></Icon>
|
||||||
|
</ListItem>
|
||||||
|
}
|
||||||
|
{_canHelp &&
|
||||||
|
<ListItem title={_t.textHelp} link="#" className='no-indicator' onClick={settingsContext.showHelp}>
|
||||||
|
<Icon slot="media" icon="icon-help"></Icon>
|
||||||
|
</ListItem>
|
||||||
|
}
|
||||||
|
{_canAbout &&
|
||||||
|
<ListItem title={_t.textAbout} link="/about/">
|
||||||
|
<Icon slot="media" icon="icon-about"></Icon>
|
||||||
|
</ListItem>
|
||||||
|
}
|
||||||
|
{_canFeedback &&
|
||||||
|
<ListItem title={t('View.Settings.textFeedback')} link="#" className='no-indicator' onClick={settingsContext.showFeedback}>
|
||||||
|
<Icon slot="media" icon="icon-feedback"></Icon>
|
||||||
|
</ListItem>
|
||||||
|
}
|
||||||
|
{canCloseEditor &&
|
||||||
|
<ListItem title={closeButtonText ?? t('View.Settings.textClose')} link="#" className='close-editor-btn no-indicator' onClick={() => Common.Notifications.trigger('close')}></ListItem>
|
||||||
|
}
|
||||||
|
</List>
|
||||||
|
</Page>
|
||||||
|
)
|
||||||
|
}));
|
||||||
|
|
||||||
|
export default SettingsPage;
|
||||||
124
apps/visioeditor/mobile/src/view/settings/VisioInfo.jsx
Normal file
124
apps/visioeditor/mobile/src/view/settings/VisioInfo.jsx
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
import React, { Fragment, useContext } from "react";
|
||||||
|
import { observer, inject } from "mobx-react";
|
||||||
|
import { Page, Navbar, List, ListItem, BlockTitle } from "framework7-react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { SettingsContext } from "../../controller/settings/Settings";
|
||||||
|
|
||||||
|
const PageVisioInfo = (props) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const _t = t("View.Settings", { returnObjects: true });
|
||||||
|
const storeInfo = props.storeVisioInfo;
|
||||||
|
const dataApp = props.getAppProps();
|
||||||
|
const dataDoc = JSON.parse(JSON.stringify(storeInfo.dataDoc));
|
||||||
|
const settingsContext = useContext(SettingsContext);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Page>
|
||||||
|
<Navbar title={_t.textVisioInfo} backLink={_t.textBack} />
|
||||||
|
{dataDoc?.title ? (
|
||||||
|
<Fragment>
|
||||||
|
<BlockTitle>{_t.textVisioTitle}</BlockTitle>
|
||||||
|
<List>
|
||||||
|
<ListItem href="#" title={dataDoc.title} onClick={settingsContext.changeTitleHandler}></ListItem>
|
||||||
|
</List>
|
||||||
|
</Fragment>
|
||||||
|
) : null}
|
||||||
|
{dataDoc?.info?.author || dataDoc?.info?.owner ? (
|
||||||
|
<Fragment>
|
||||||
|
<BlockTitle>{_t.textOwner}</BlockTitle>
|
||||||
|
<List>
|
||||||
|
<ListItem title={dataDoc.info.author || dataDoc.info.owner}></ListItem>
|
||||||
|
</List>
|
||||||
|
</Fragment>
|
||||||
|
) : null}
|
||||||
|
{dataDoc?.info?.folder ? (
|
||||||
|
<Fragment>
|
||||||
|
<BlockTitle>{_t.textLocation}</BlockTitle>
|
||||||
|
<List>
|
||||||
|
<ListItem title={dataDoc.info.folder}></ListItem>
|
||||||
|
</List>
|
||||||
|
</Fragment>
|
||||||
|
) : null}
|
||||||
|
{dataDoc?.info?.uploaded || dataDoc?.info?.created ? (
|
||||||
|
<Fragment>
|
||||||
|
<BlockTitle>{_t.textUploaded}</BlockTitle>
|
||||||
|
<List>
|
||||||
|
<ListItem title={dataDoc.info.uploaded || dataDoc.info.created}></ListItem>
|
||||||
|
</List>
|
||||||
|
</Fragment>
|
||||||
|
) : null}
|
||||||
|
{props.title ? (
|
||||||
|
<Fragment>
|
||||||
|
<BlockTitle>{_t.textTitle}</BlockTitle>
|
||||||
|
<List>
|
||||||
|
<ListItem title={props.title}></ListItem>
|
||||||
|
</List>
|
||||||
|
</Fragment>
|
||||||
|
) : null}
|
||||||
|
{props.subject ? (
|
||||||
|
<Fragment>
|
||||||
|
<BlockTitle>{_t.textSubject}</BlockTitle>
|
||||||
|
<List>
|
||||||
|
<ListItem title={props.subject}></ListItem>
|
||||||
|
</List>
|
||||||
|
</Fragment>
|
||||||
|
) : null}
|
||||||
|
{props.description ? (
|
||||||
|
<Fragment>
|
||||||
|
<BlockTitle>{_t.textComment}</BlockTitle>
|
||||||
|
<List>
|
||||||
|
<ListItem title={props.description}></ListItem>
|
||||||
|
</List>
|
||||||
|
</Fragment>
|
||||||
|
) : null}
|
||||||
|
{props.modified ? (
|
||||||
|
<Fragment>
|
||||||
|
<BlockTitle>{_t.textLastModified}</BlockTitle>
|
||||||
|
<List>
|
||||||
|
<ListItem title={props.modified}></ListItem>
|
||||||
|
</List>
|
||||||
|
</Fragment>
|
||||||
|
) : null}
|
||||||
|
{props.modifiedBy ? (
|
||||||
|
<Fragment>
|
||||||
|
<BlockTitle>{_t.textLastModifiedBy}</BlockTitle>
|
||||||
|
<List>
|
||||||
|
<ListItem title={props.modifiedBy}></ListItem>
|
||||||
|
</List>
|
||||||
|
</Fragment>
|
||||||
|
) : null}
|
||||||
|
{props.created ? (
|
||||||
|
<Fragment>
|
||||||
|
<BlockTitle>{_t.textCreated}</BlockTitle>
|
||||||
|
<List>
|
||||||
|
<ListItem title={props.created}></ListItem>
|
||||||
|
</List>
|
||||||
|
</Fragment>
|
||||||
|
) : null}
|
||||||
|
{dataApp ? (
|
||||||
|
<Fragment>
|
||||||
|
<BlockTitle>{_t.textApplication}</BlockTitle>
|
||||||
|
<List>
|
||||||
|
<ListItem title={dataApp}></ListItem>
|
||||||
|
</List>
|
||||||
|
</Fragment>
|
||||||
|
) : null}
|
||||||
|
{props.creators ? (
|
||||||
|
<Fragment>
|
||||||
|
<BlockTitle>{_t.textAuthor}</BlockTitle>
|
||||||
|
<List>
|
||||||
|
{
|
||||||
|
props.creators.split(/\s*[,;]\s*/).map(item => {
|
||||||
|
return <ListItem key="item" title={item}></ListItem>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</List>
|
||||||
|
</Fragment>
|
||||||
|
) : null}
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const VisioInfo = inject("storeVisioInfo")(observer(PageVisioInfo));
|
||||||
|
|
||||||
|
export default VisioInfo;
|
||||||
@ -668,7 +668,8 @@ module.exports = function(grunt) {
|
|||||||
},
|
},
|
||||||
cmd: function() {
|
cmd: function() {
|
||||||
const editor = packageFile.name == 'presentationeditor' ? 'slide' :
|
const editor = packageFile.name == 'presentationeditor' ? 'slide' :
|
||||||
packageFile.name == 'spreadsheeteditor' ? 'cell' : 'word';
|
packageFile.name == 'spreadsheeteditor' ? 'cell' :
|
||||||
|
packageFile.name == 'visioeditor' ? 'visio' : 'word';
|
||||||
return `npm run deploy-${editor}`;
|
return `npm run deploy-${editor}`;
|
||||||
|
|
||||||
// const addon_path = `${packageFile.mobile.js.reactjs && !!packageFile.mobile.js.reactjs.features ? `ADDON_ENV=${packageFile.mobile.js.reactjs.features}` : ''}`;
|
// const addon_path = `${packageFile.mobile.js.reactjs && !!packageFile.mobile.js.reactjs.features ? `ADDON_ENV=${packageFile.mobile.js.reactjs.features}` : ''}`;
|
||||||
|
|||||||
@ -206,10 +206,120 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mobile": {
|
||||||
|
"clean": {
|
||||||
|
"deploy": [
|
||||||
|
"../deploy/web-apps/apps/visioeditor/mobile"
|
||||||
|
],
|
||||||
|
"template-backup": [
|
||||||
|
"../apps/visioeditor/mobile/app/template/backup"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"js": {
|
||||||
|
"src": "../apps/visioeditor/mobile/dist/js/app.js",
|
||||||
|
"dest": "../deploy/web-apps/apps/visioeditor/mobile/dist/js/app.js"
|
||||||
|
},
|
||||||
|
"css": {
|
||||||
|
"ios": {
|
||||||
|
"src": [
|
||||||
|
"../apps/visioeditor/mobile/resources/css/app-ios.css"
|
||||||
|
],
|
||||||
|
"dist": "../deploy/web-apps/apps/visioeditor/mobile/resources/css/app-ios.css"
|
||||||
|
},
|
||||||
|
"material": {
|
||||||
|
"src": [
|
||||||
|
"../apps/visioeditor/mobile/resources/css/app-material.css"
|
||||||
|
],
|
||||||
|
"dist": "../deploy/web-apps/apps/visioeditor/mobile/resources/css/app-material.css"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"htmlmin": {
|
||||||
|
"templates": [
|
||||||
|
{
|
||||||
|
"expand": true,
|
||||||
|
"cwd": "../apps/visioeditor/mobile/app/template/",
|
||||||
|
"src": "*.template",
|
||||||
|
"dest": "../apps/visioeditor/mobile/app/template/"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"jsonmin": {
|
||||||
|
"files": "../deploy/web-apps/apps/visioeditor/mobile/**/*.json"
|
||||||
|
},
|
||||||
|
"copy": {
|
||||||
|
"assets": [
|
||||||
|
{
|
||||||
|
"expand": true,
|
||||||
|
"cwd": "../apps/visioeditor/mobile/css",
|
||||||
|
"src": "*.css",
|
||||||
|
"dest": "../deploy/web-apps/apps/visioeditor/mobile/css"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"expand": true,
|
||||||
|
"cwd": "../apps/visioeditor/mobile/dist",
|
||||||
|
"src": "**",
|
||||||
|
"dest": "../deploy/web-apps/apps/visioeditor/mobile/dist"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"template-backup": [
|
||||||
|
{
|
||||||
|
"expand": true,
|
||||||
|
"cwd": "../apps/visioeditor/mobile/app/template/",
|
||||||
|
"src": "*.template",
|
||||||
|
"dest": "../apps/visioeditor/mobile/app/template/backup/",
|
||||||
|
"filter": "isFile"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"template-restore": [
|
||||||
|
{
|
||||||
|
"expand": true,
|
||||||
|
"cwd": "../apps/visioeditor/mobile/app/template/backup/",
|
||||||
|
"src": "*.template",
|
||||||
|
"dest": "../apps/visioeditor/mobile/app/template/",
|
||||||
|
"filter": "isFile"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index-page": {
|
||||||
|
"../deploy/web-apps/apps/visioeditor/mobile/index.html": "../apps/visioeditor/mobile/index.html",
|
||||||
|
"../deploy/web-apps/apps/visioeditor/mobile/index_loader.html": "../apps/visioeditor/mobile/index.html"
|
||||||
|
},
|
||||||
|
"localization": [
|
||||||
|
{
|
||||||
|
"expand": true,
|
||||||
|
"cwd": "../apps/visioeditor/mobile/locale/",
|
||||||
|
"src": "*",
|
||||||
|
"dest": "../deploy/web-apps/apps/visioeditor/mobile/locale/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"images-app": [
|
||||||
|
{
|
||||||
|
"expand": true,
|
||||||
|
"cwd": "../apps/visioeditor/mobile/resources/img/",
|
||||||
|
"src": "**/*.{png,svg}",
|
||||||
|
"dest": "../deploy/web-apps/apps/visioeditor/mobile/resources/img/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"images-common": [
|
||||||
|
{
|
||||||
|
"expand": true,
|
||||||
|
"cwd": "../apps/common/mobile/resources/img/",
|
||||||
|
"src": "**",
|
||||||
|
"dest": "../deploy/web-apps/apps/visioeditor/mobile/resources/img/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"expand": true,
|
||||||
|
"cwd": "../apps/common/main/resources/img/about",
|
||||||
|
"src": "**",
|
||||||
|
"dest": "../deploy/web-apps/apps/visioeditor/mobile/resources/img/about"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"tasks": {
|
"tasks": {
|
||||||
"deploy": [
|
"deploy": [
|
||||||
"increment-build",
|
"increment-build",
|
||||||
"deploy-app-main"
|
"deploy-app-main",
|
||||||
|
"deploy-app-mobile"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -18,7 +18,8 @@ function resolvePath(dir) {
|
|||||||
const env = process.env.NODE_ENV || 'development';
|
const env = process.env.NODE_ENV || 'development';
|
||||||
const target = process.env.TARGET || 'web';
|
const target = process.env.TARGET || 'web';
|
||||||
const editor = process.env.TARGET_EDITOR === 'cell' ? 'spreadsheeteditor' :
|
const editor = process.env.TARGET_EDITOR === 'cell' ? 'spreadsheeteditor' :
|
||||||
process.env.TARGET_EDITOR === 'slide' ? 'presentationeditor' : 'documenteditor';
|
process.env.TARGET_EDITOR === 'slide' ? 'presentationeditor' :
|
||||||
|
process.env.TARGET_EDITOR === 'visio' ? 'visioeditor' : 'documenteditor';
|
||||||
const targetPatch = process.env.TARGET_EDITOR || 'word';
|
const targetPatch = process.env.TARGET_EDITOR || 'word';
|
||||||
const addonPath = process.env.ADDON_ENV || 'path';
|
const addonPath = process.env.ADDON_ENV || 'path';
|
||||||
|
|
||||||
@ -112,6 +113,7 @@ const config = {
|
|||||||
resolvePath('node_modules/ssr-window'),
|
resolvePath('node_modules/ssr-window'),
|
||||||
resolvePath('../../../web-apps-mobile/word'),
|
resolvePath('../../../web-apps-mobile/word'),
|
||||||
resolvePath('../../../web-apps-mobile/slide'),
|
resolvePath('../../../web-apps-mobile/slide'),
|
||||||
|
resolvePath('../../../web-apps-mobile/visio'),
|
||||||
resolvePath('../../../web-apps-mobile/cell')
|
resolvePath('../../../web-apps-mobile/cell')
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
4
vendor/framework7-react/package.json
vendored
4
vendor/framework7-react/package.json
vendored
@ -13,10 +13,12 @@
|
|||||||
"deploy-word": "cross-env TARGET_EDITOR=word NODE_ENV=production node ./build/build.js",
|
"deploy-word": "cross-env TARGET_EDITOR=word NODE_ENV=production node ./build/build.js",
|
||||||
"deploy-cell": "cross-env TARGET_EDITOR=cell NODE_ENV=production node ./build/build.js",
|
"deploy-cell": "cross-env TARGET_EDITOR=cell NODE_ENV=production node ./build/build.js",
|
||||||
"deploy-slide": "cross-env TARGET_EDITOR=slide NODE_ENV=production node ./build/build.js",
|
"deploy-slide": "cross-env TARGET_EDITOR=slide NODE_ENV=production node ./build/build.js",
|
||||||
|
"deploy-visio": "cross-env TARGET_EDITOR=visio NODE_ENV=production node ./build/build.js",
|
||||||
"postinstall1": "cpy ./node_modules/framework7-icons/fonts/*.* ./src/fonts/",
|
"postinstall1": "cpy ./node_modules/framework7-icons/fonts/*.* ./src/fonts/",
|
||||||
"build-word": "cross-env NODE_ENV=development node ./build/build.js",
|
"build-word": "cross-env NODE_ENV=development node ./build/build.js",
|
||||||
"build-slide": "cross-env NODE_ENV=development TARGET_EDITOR=slide node ./build/build.js",
|
"build-slide": "cross-env NODE_ENV=development TARGET_EDITOR=slide node ./build/build.js",
|
||||||
"build-cell": "cross-env NODE_ENV=development TARGET_EDITOR=cell node ./build/build.js"
|
"build-cell": "cross-env NODE_ENV=development TARGET_EDITOR=cell node ./build/build.js",
|
||||||
|
"build-visio": "cross-env NODE_ENV=development TARGET_EDITOR=visio node ./build/build.js"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
|
|||||||
Reference in New Issue
Block a user