diff --git a/apps/common/mobile/lib/view/About.jsx b/apps/common/mobile/lib/view/About.jsx
index a78dd577d..cb6035fa7 100644
--- a/apps/common/mobile/lib/view/About.jsx
+++ b/apps/common/mobile/lib/view/About.jsx
@@ -119,5 +119,7 @@ const PageAbout = props => {
};
const About = inject("storeAppOptions")(observer(PageAbout));
+About.appVersion = () => (__PRODUCT_VERSION__);
+
export default About;
\ No newline at end of file
diff --git a/apps/documenteditor/mobile/locale/en.json b/apps/documenteditor/mobile/locale/en.json
index aecdb7ff9..e2d292591 100644
--- a/apps/documenteditor/mobile/locale/en.json
+++ b/apps/documenteditor/mobile/locale/en.json
@@ -26,7 +26,25 @@
"List Paragraph": "List Paragraph",
"footnote text": "Footnote Text"
},
- "leavePageText": "You have unsaved changes in this document. Click 'Stay on this Page' to await the autosave of the document. Click 'Leave this Page' to discard all the unsaved changes."
+ "leavePageText": "You have unsaved changes in this document. Click 'Stay on this Page' to await the autosave of the document. Click 'Leave this Page' to discard all the unsaved changes.",
+ "titleLicenseExp": "License expired",
+ "warnLicenseExp": "Your license has expired. Please update your license and refresh the page.",
+ "errorServerVersion": "The editor version has been updated. The page will be reloaded to apply the changes.",
+ "titleServerVersion": "Editor updated",
+ "notcriticalErrorTitle": "Warning",
+ "errorOpensource": "Using the free Community version you can open documents for viewing only. To access mobile web editors, a commercial license is required.",
+ "warnLicenseLimitedNoAccess": "License expired. You have no access to document editing functionality. Please contact your administrator.",
+ "warnLicenseLimitedRenewed": "License needs to be renewed. You have a limited access to document editing functionality.
Please contact your administrator to get full access",
+ "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.",
+ "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.",
+ "textBuyNow": "Visit website",
+ "textContactUs": "Contact sales",
+ "textNoLicenseTitle": "License limit reached",
+ "textPaidFeature": "Paid feature",
+ "textCustomLoader": "Please note that according to the terms of the license you are not entitled to change the loader. Please contact our Sales Department to get a quote.",
+ "textClose": "Close"
},
"Toolbar": {
"dlgLeaveTitleText": "You leave the application",
diff --git a/apps/documenteditor/mobile/src/controller/Main.jsx b/apps/documenteditor/mobile/src/controller/Main.jsx
index 540ca4398..0051a04e5 100644
--- a/apps/documenteditor/mobile/src/controller/Main.jsx
+++ b/apps/documenteditor/mobile/src/controller/Main.jsx
@@ -13,6 +13,7 @@ import {
EditCommentController,
ViewCommentsController
} from "../../../../common/mobile/lib/controller/collaboration/Comments";
+import About from '../../../../common/mobile/lib/view/About';
import patch from '../lib/patch'
@@ -30,6 +31,13 @@ class MainController extends Component {
constructor(props) {
super(props);
window.editorType = 'de';
+
+ this._state = {
+ licenseType: false
+ };
+
+ const { t } = this.props;
+ this._t = t('Main', {returnObjects:true});
}
initSdk() {
@@ -112,7 +120,7 @@ class MainController extends Component {
this.api.asc_registerCallback('asc_onGetEditorPermissions', onEditorPermissions);
this.api.asc_registerCallback('asc_onDocumentContentReady', onDocumentContentReady);
- // this.api.asc_registerCallback('asc_onLicenseChanged', _.bind(this.onLicenseChanged, this));
+ this.api.asc_registerCallback('asc_onLicenseChanged', this.onLicenseChanged.bind(this));
// this.api.asc_registerCallback('asc_onRunAutostartMacroses', _.bind(this.onRunAutostartMacroses, this));
this.api.asc_setDocInfo(docInfo);
this.api.asc_getEditorPermissions(this.editorConfig.licenseUrl, this.editorConfig.customerId);
@@ -138,6 +146,20 @@ class MainController extends Component {
const licType = params.asc_getLicenseType();
// check licType
+ if (Asc.c_oLicenseResult.Expired === licType ||
+ Asc.c_oLicenseResult.Error === licType ||
+ Asc.c_oLicenseResult.ExpiredTrial === licType) {
+ f7.dialog.create({
+ title : this._t.titleLicenseExp,
+ text : this._t.warnLicenseExp
+ }).open();
+ return;
+ }
+ if (Asc.c_oLicenseResult.ExpiredLimited === licType) {
+ this._state.licenseType = licType;
+ }
+
+ if ( this.onServerVersion(params.asc_getBuildVersion()) ) return;
this.appOptions.canLicense = (licType === Asc.c_oLicenseResult.Success || licType === Asc.c_oLicenseResult.SuccessLimit);
@@ -158,6 +180,8 @@ class MainController extends Component {
f7.emit('resize');
Common.Notifications.trigger('document:ready');
+
+ this._isDocReady = true;
};
const _process_array = (array, fn) => {
@@ -241,9 +265,7 @@ class MainController extends Component {
this.api.asc_continueSaving();
}, 500);
- const { t } = this.props;
- const _t = t('Main', {returnObjects:true})
- return _t.leavePageText;
+ return this._t.leavePageText;
}
}
@@ -252,8 +274,118 @@ class MainController extends Component {
clearTimeout(this.continueSavingTimer);
}
- applyLicense () {
+ onLicenseChanged (params) {
+ const appOptions = this.props.storeAppOptions;
+ const licType = params.asc_getLicenseType();
+ if (licType !== undefined && appOptions.canEdit && 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 (this._isDocReady && this._state.licenseType)
+ this.applyLicense();
+ }
+ applyLicense () {
+ const _t = this._t;
+ const appOptions = this.props.storeAppOptions;
+ if (appOptions.config.mode !== 'view' && !patch.isSupportEditFeature()) {
+ let value = LocalStorage.getItem("de-opensource-warning");
+ value = (value !== null) ? parseInt(value) : 0;
+ const now = (new Date).getTime();
+ if (now - value > 86400000) {
+ LocalStorage.setItem("de-opensource-warning", now);
+ f7.dialog.create({
+ title: _t.notcriticalErrorTitle,
+ text : _t.errorOpensource,
+ buttons: [{text: 'OK'}]
+ }).open();
+ }
+ Common.Notifications.trigger('toolbar:activatecontrols');
+ return;
+ }
+
+ if (this._state.licenseType) {
+ let license = this._state.licenseType;
+ let buttons = [{text: 'OK'}];
+ if ((appOptions.trialMode & Asc.c_oLicenseMode.Limited) !== 0 &&
+ (license === Asc.c_oLicenseResult.SuccessLimit ||
+ license === Asc.c_oLicenseResult.ExpiredLimited ||
+ appOptions.permissionsLicense === Asc.c_oLicenseResult.SuccessLimit)
+ ) {
+ license = (license === Asc.c_oLicenseResult.ExpiredLimited) ? _t.warnLicenseLimitedNoAccess : _t.warnLicenseLimitedRenewed;
+ } else if (license === Asc.c_oLicenseResult.Connections || license === Asc.c_oLicenseResult.UsersCount) {
+ license = (license===Asc.c_oLicenseResult.Connections) ? _t.warnLicenseExceeded : _t.warnLicenseUsersExceeded;
+ } else {
+ license = (license === Asc.c_oLicenseResult.ConnectionsOS) ? _t.warnNoLicense : _t.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');
+ Common.Notifications.trigger('toolbar:deactivateeditcontrols');
+ Common.Notifications.trigger('api:disconnect');
+ }
+
+ let value = LocalStorage.getItem("de-license-warning");
+ value = (value !== null) ? parseInt(value) : 0;
+ const now = (new Date).getTime();
+
+ if (now - value > 86400000) {
+ LocalStorage.setItem("de-license-warning", now);
+ f7.dialog.create({
+ title: _t.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');
+ }
+ }
+
+ onServerVersion (buildVersion) {
+ if (this.changeServerVersion) return true;
+ const _t = this._t;
+
+ 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;
}
bindEvents() {
diff --git a/apps/documenteditor/mobile/src/controller/Toolbar.jsx b/apps/documenteditor/mobile/src/controller/Toolbar.jsx
index 53c8683d5..609c072fe 100644
--- a/apps/documenteditor/mobile/src/controller/Toolbar.jsx
+++ b/apps/documenteditor/mobile/src/controller/Toolbar.jsx
@@ -22,6 +22,8 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeReview')(prop
api.asc_registerCallback('asc_onFocusObject', onApiFocusObject);
api.asc_registerCallback('asc_onCoAuthoringDisconnect', onCoAuthoringDisconnect);
Common.Notifications.on('api:disconnect', onCoAuthoringDisconnect);
+ Common.Notifications.on('toolbar:activatecontrols', activateControls);
+ Common.Notifications.on('toolbar:deactivateeditcontrols', deactivateEditControls);
};
if ( !Common.EditorApi ) {
Common.Notifications.on('document:ready', onDocumentReady);
@@ -35,6 +37,8 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeReview')(prop
Common.Notifications.off('document:ready', onDocumentReady);
Common.Notifications.off('setdoctitle', setDocTitle);
Common.Notifications.off('api:disconnect', onCoAuthoringDisconnect);
+ Common.Notifications.off('toolbar:activatecontrols', activateControls);
+ Common.Notifications.off('toolbar:deactivateeditcontrols', deactivateEditControls);
const api = Common.EditorApi.get();
api.asc_unregisterCallback('asc_onCanUndo', onApiCanUndo);
@@ -163,6 +167,11 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeReview')(prop
f7.popup.close();
};
+ const [disabledControls, setDisabledControls] = useState(true);
+ const activateControls = () => {
+ setDisabledControls(false);
+ };
+
return (
{
return (
- {props.isShowBack && }
+ {props.isShowBack && }
{!Device.phone && {props.docTitle}}
- props.openOptions('edit')}>
- props.openOptions('add')}>
- { Device.phone ? null : }
- {props.displayCollaboration && props.openOptions('coauth')}>}
- props.openOptions('settings')}>
+ props.openOptions('edit')}>
+ props.openOptions('add')}>
+ { Device.phone ? null : }
+ {props.displayCollaboration && props.openOptions('coauth')}>}
+ props.openOptions('settings')}>
)
diff --git a/vendor/framework7-react/build/webpack.config.js b/vendor/framework7-react/build/webpack.config.js
index ea3bc262f..fd4ef23c5 100644
--- a/vendor/framework7-react/build/webpack.config.js
+++ b/vendor/framework7-react/build/webpack.config.js
@@ -156,7 +156,7 @@ module.exports = {
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(env),
'process.env.TARGET': JSON.stringify(target),
- __PRODUCT_VERSION__: JSON.stringify(process.env.PRODUCT_VERSION ? process.env.PRODUCT_VERSION : '0.0.1'),
+ __PRODUCT_VERSION__: JSON.stringify(process.env.PRODUCT_VERSION ? process.env.PRODUCT_VERSION : '6.2.0'),
__PUBLISHER_ADDRESS__: JSON.stringify('20A-12 Ernesta Birznieka-Upisha street, Riga, Latvia, EU, LV-1050'),
__SUPPORT_EMAIL__: JSON.stringify('support@onlyoffice.com'),
__PUBLISHER_PHONE__: JSON.stringify('+371 633-99867'),