From 90b613d88d30c06db247f5c2444f93c51a05e3e1 Mon Sep 17 00:00:00 2001 From: SergeyEzhin Date: Thu, 18 Mar 2021 17:00:52 +0300 Subject: [PATCH 01/43] [mobile] Corrected some elements --- .../mobile/src/controller/Main.jsx | 5 ++++ .../mobile/src/store/focusObjects.js | 6 ++-- .../mobile/src/view/edit/EditImage.jsx | 4 +-- .../mobile/src/view/edit/EditTable.jsx | 4 +-- .../mobile/src/view/edit/EditText.jsx | 1 + .../mobile/src/view/settings/Settings.jsx | 29 +++++++++++++++++-- .../mobile/src/controller/Main.jsx | 2 ++ .../mobile/src/view/edit/EditTable.jsx | 12 ++++---- .../mobile/src/view/settings/Settings.jsx | 3 +- .../mobile/src/view/settings/Settings.jsx | 3 +- .../framework7-react/build/webpack.config.js | 1 + 11 files changed, 54 insertions(+), 16 deletions(-) diff --git a/apps/documenteditor/mobile/src/controller/Main.jsx b/apps/documenteditor/mobile/src/controller/Main.jsx index 564edf439..05824fd1d 100644 --- a/apps/documenteditor/mobile/src/controller/Main.jsx +++ b/apps/documenteditor/mobile/src/controller/Main.jsx @@ -251,10 +251,15 @@ class MainController extends Component { switch (type) { case 0: storeTextSettings.resetBullets(subtype); + storeTextSettings.resetNumbers(-1); break; case 1: storeTextSettings.resetNumbers(subtype); + storeTextSettings.resetBullets(-1); break; + default: + storeTextSettings.resetBullets(-1); + storeTextSettings.resetNumbers(-1); } }); this.api.asc_registerCallback('asc_onPrAlign', (align) => { diff --git a/apps/documenteditor/mobile/src/store/focusObjects.js b/apps/documenteditor/mobile/src/store/focusObjects.js index b9a9f4e16..cb27b16d0 100644 --- a/apps/documenteditor/mobile/src/store/focusObjects.js +++ b/apps/documenteditor/mobile/src/store/focusObjects.js @@ -155,8 +155,10 @@ export class storeFocusObjects { get chartObject() { const charts = []; for (let object of this._focusObjects) { - if (object.get_ObjectValue() && object.get_ObjectValue().get_ChartProperties()) { - charts.push(object); + if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Image) { + if (object.get_ObjectValue() && object.get_ObjectValue().get_ChartProperties()) { + charts.push(object); + } } } if (charts.length > 0) { diff --git a/apps/documenteditor/mobile/src/view/edit/EditImage.jsx b/apps/documenteditor/mobile/src/view/edit/EditImage.jsx index bcc3f97ce..106408d41 100644 --- a/apps/documenteditor/mobile/src/view/edit/EditImage.jsx +++ b/apps/documenteditor/mobile/src/view/edit/EditImage.jsx @@ -76,10 +76,10 @@ const PageWrap = props => { } - {props.onMoveText(!moveText)}}/> + {props.onMoveText(!moveText)}}/> - {props.onOverlap(!overlap)}}/> + {props.onOverlap(!overlap)}}/> { diff --git a/apps/documenteditor/mobile/src/view/edit/EditTable.jsx b/apps/documenteditor/mobile/src/view/edit/EditTable.jsx index 01efdba28..3dfc883ab 100644 --- a/apps/documenteditor/mobile/src/view/edit/EditTable.jsx +++ b/apps/documenteditor/mobile/src/view/edit/EditTable.jsx @@ -70,10 +70,10 @@ const PageWrap = props => { - {props.onWrapType(c_tableWrap.TABLE_WRAP_NONE)}}> + {props.onWrapType(c_tableWrap.TABLE_WRAP_NONE)}}> {!isAndroid && } - {props.onWrapType(c_tableWrap.TABLE_WRAP_PARALLEL)}}> + {props.onWrapType(c_tableWrap.TABLE_WRAP_PARALLEL)}}> {!isAndroid && } diff --git a/apps/documenteditor/mobile/src/view/edit/EditText.jsx b/apps/documenteditor/mobile/src/view/edit/EditText.jsx index 93b114610..c1df19309 100644 --- a/apps/documenteditor/mobile/src/view/edit/EditText.jsx +++ b/apps/documenteditor/mobile/src/view/edit/EditText.jsx @@ -131,6 +131,7 @@ const PageBullets = props => { ]; const storeTextSettings = props.storeTextSettings; const typeBullets = storeTextSettings.typeBullets; + return( diff --git a/apps/documenteditor/mobile/src/view/settings/Settings.jsx b/apps/documenteditor/mobile/src/view/settings/Settings.jsx index a199d82e3..63e744df1 100644 --- a/apps/documenteditor/mobile/src/view/settings/Settings.jsx +++ b/apps/documenteditor/mobile/src/view/settings/Settings.jsx @@ -72,6 +72,31 @@ const SettingsList = inject("storeAppOptions")( observer( withTranslation()( pro } }; + const onPrint = () => { + closeModal(); + const api = Common.EditorApi.get(); + api.asc_Print(); + }; + + const showHelp = () => { + 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"); + }; + useEffect(() => { }); @@ -138,7 +163,7 @@ const SettingsList = inject("storeAppOptions")( observer( withTranslation()( pro } {_canPrint && - + } @@ -146,7 +171,7 @@ const SettingsList = inject("storeAppOptions")( observer( withTranslation()( pro {_canHelp && - + } diff --git a/apps/presentationeditor/mobile/src/controller/Main.jsx b/apps/presentationeditor/mobile/src/controller/Main.jsx index d8ee673da..8d67cd2bf 100644 --- a/apps/presentationeditor/mobile/src/controller/Main.jsx +++ b/apps/presentationeditor/mobile/src/controller/Main.jsx @@ -265,9 +265,11 @@ class MainController extends Component { switch (type) { case 0: storeTextSettings.resetBullets(subtype); + storeTextSettings.resetNumbers(-1); break; case 1: storeTextSettings.resetNumbers(subtype); + storeTextSettings.resetBullets(-1); break; default: storeTextSettings.resetBullets(-1); diff --git a/apps/presentationeditor/mobile/src/view/edit/EditTable.jsx b/apps/presentationeditor/mobile/src/view/edit/EditTable.jsx index 8786cc95e..0529639f4 100644 --- a/apps/presentationeditor/mobile/src/view/edit/EditTable.jsx +++ b/apps/presentationeditor/mobile/src/view/edit/EditTable.jsx @@ -60,24 +60,24 @@ const PageStyleOptions = props => { - {props.onCheckTemplateChange(tableLook, 0, !isFirstRow)}}/> + {props.onCheckTemplateChange(tableLook, 0, !isFirstRow)}}/> - {props.onCheckTemplateChange(tableLook, 1, !isLastRow)}}/> + {props.onCheckTemplateChange(tableLook, 1, !isLastRow)}}/> - {props.onCheckTemplateChange(tableLook, 2, !isBandHor)}}/> + {props.onCheckTemplateChange(tableLook, 2, !isBandHor)}}/> - {props.onCheckTemplateChange(tableLook, 3, !isFirstCol)}}/> + {props.onCheckTemplateChange(tableLook, 3, !isFirstCol)}}/> - {props.onCheckTemplateChange(tableLook, 4, !isLastCol)}}/> + {props.onCheckTemplateChange(tableLook, 4, !isLastCol)}}/> - {props.onCheckTemplateChange(tableLook, 5, !isBandVer)}}/> + {props.onCheckTemplateChange(tableLook, 5, !isBandVer)}}/> diff --git a/apps/presentationeditor/mobile/src/view/settings/Settings.jsx b/apps/presentationeditor/mobile/src/view/settings/Settings.jsx index 43deb4bdf..7f36baaf5 100644 --- a/apps/presentationeditor/mobile/src/view/settings/Settings.jsx +++ b/apps/presentationeditor/mobile/src/view/settings/Settings.jsx @@ -83,7 +83,8 @@ const SettingsList = withTranslation()(props => { const showHelp = () => { // let url = '{{HELP_URL}}'; - let url = 'https://helpcenter.onlyoffice.com'; + let url = __HELP_URL__; + // let url = 'https://helpcenter.onlyoffice.com'; if (url.charAt(url.length-1) !== '/') { url += '/'; diff --git a/apps/spreadsheeteditor/mobile/src/view/settings/Settings.jsx b/apps/spreadsheeteditor/mobile/src/view/settings/Settings.jsx index 938900eff..485eb9bf8 100644 --- a/apps/spreadsheeteditor/mobile/src/view/settings/Settings.jsx +++ b/apps/spreadsheeteditor/mobile/src/view/settings/Settings.jsx @@ -91,7 +91,8 @@ const SettingsList = withTranslation()(props => { const showHelp = () => { // let url = '{{HELP_URL}}'; - let url = 'https://helpcenter.onlyoffice.com'; + // let url = 'https://helpcenter.onlyoffice.com'; + let url = __HELP_URL__; if (url.charAt(url.length-1) !== '/') { url += '/'; diff --git a/vendor/framework7-react/build/webpack.config.js b/vendor/framework7-react/build/webpack.config.js index 8d4fc4a43..42acab398 100644 --- a/vendor/framework7-react/build/webpack.config.js +++ b/vendor/framework7-react/build/webpack.config.js @@ -159,6 +159,7 @@ module.exports = { __PUBLISHER_PHONE__: JSON.stringify('+371 633-99867'), __PUBLISHER_URL__: JSON.stringify('https://www.onlyoffice.com'), __PUBLISHER_NAME__: JSON.stringify('Ascensio System SIA'), + __HELP_URL__: JSON.stringify('https://helpcenter.onlyoffice.com'), }), ...(env === 'production' ? [ From 722bc4b01414bb97fccf6a8ce8a03cc6025850ed Mon Sep 17 00:00:00 2001 From: SergeyEzhin Date: Mon, 29 Mar 2021 22:10:45 +0300 Subject: [PATCH 02/43] [SSE mobile] Correct tabs is Statusbar --- .../mobile/src/controller/Statusbar.jsx | 13 ++++++------- .../mobile/src/less/statusbar.less | 6 ++++-- apps/spreadsheeteditor/mobile/src/store/sheets.js | 8 -------- .../spreadsheeteditor/mobile/src/view/Statusbar.jsx | 2 +- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/apps/spreadsheeteditor/mobile/src/controller/Statusbar.jsx b/apps/spreadsheeteditor/mobile/src/controller/Statusbar.jsx index b8783e196..897d5b36c 100644 --- a/apps/spreadsheeteditor/mobile/src/controller/Statusbar.jsx +++ b/apps/spreadsheeteditor/mobile/src/controller/Statusbar.jsx @@ -70,7 +70,7 @@ const Statusbar = inject('sheets', 'storeAppOptions', 'users')(props => { const sheets_count = api.asc_getWorksheetsCount(); const active_index = api.asc_getActiveWorksheetIndex(); - let i = -1, items = [], hiddentems = []; + let i = -1, items = []; while (++i < sheets_count) { const tab = { @@ -82,13 +82,11 @@ const Statusbar = inject('sheets', 'storeAppOptions', 'users')(props => { color : api.asc_getWorksheetTabColor(i) }; - (api.asc_isWorksheetHidden(i) ? hiddentems : items).push(tab); - // items.push(tab); + // (api.asc_isWorksheetHidden(i) ? hiddentems : items).push(tab); + items.push(tab); } sheets.resetSheets(items); - sheets.resetHiddenSheets(hiddentems); - updateTabsColors(); }; @@ -107,6 +105,7 @@ const Statusbar = inject('sheets', 'storeAppOptions', 'users')(props => { }; const setTabLineColor = (tab, color) => { + console.log(tab); if (tab) { if (null !== color) { color = '#' + Common.Utils.ThemeColor.getHexColor(color.get_r(), color.get_g(), color.get_b()); @@ -121,9 +120,9 @@ const Statusbar = inject('sheets', 'storeAppOptions', 'users')(props => { color = '0px 4px 0 ' + color + ' inset'; } - $$('.sheet-tabs .tab').eq(tab.index).css('box-shadow', color); + $$('.sheet-tabs .tab a').eq(tab.index).css('box-shadow', color); } else { - $$('.sheet-tabs .tab').eq(tab.index).css('box-shadow', ''); + $$('.sheet-tabs .tab a').eq(tab.index).css('box-shadow', ''); } } }; diff --git a/apps/spreadsheeteditor/mobile/src/less/statusbar.less b/apps/spreadsheeteditor/mobile/src/less/statusbar.less index e2dc8269a..d0349cf0a 100644 --- a/apps/spreadsheeteditor/mobile/src/less/statusbar.less +++ b/apps/spreadsheeteditor/mobile/src/less/statusbar.less @@ -16,7 +16,7 @@ min-width: 48px; display: inline-block; - padding: 0 10px; + // padding: 0 10px; text-align: center; height: 100%; position: relative; @@ -45,9 +45,11 @@ > li { a { font-size: 12px; - padding: 0 10px 0; + padding: 0 20px 0; line-height: @statusbar-height; color: @text-normal; + height: 100%; + display: block; } &:not(.active) { diff --git a/apps/spreadsheeteditor/mobile/src/store/sheets.js b/apps/spreadsheeteditor/mobile/src/store/sheets.js index b0a592be0..bb79938d3 100644 --- a/apps/spreadsheeteditor/mobile/src/store/sheets.js +++ b/apps/spreadsheeteditor/mobile/src/store/sheets.js @@ -21,28 +21,20 @@ class Worksheet { export class storeWorksheets { sheets; - hiddensheets; constructor() { makeObservable(this, { sheets: observable, - hiddensheets: observable, resetSheets: action, - resetHiddenSheets: action, setActiveWorksheet: action }); this.sheets = []; - this.hiddensheets = []; } resetSheets(sheets) { this.sheets = Object.values(sheets) } - resetHiddenSheets(hiddensheets) { - this.hiddensheets = Object.values(hiddensheets) - } - setActiveWorksheet(i) { if ( !this.sheets[i].active ) { this.sheets.forEach(model => { diff --git a/apps/spreadsheeteditor/mobile/src/view/Statusbar.jsx b/apps/spreadsheeteditor/mobile/src/view/Statusbar.jsx index d0d7fea21..088994c5f 100644 --- a/apps/spreadsheeteditor/mobile/src/view/Statusbar.jsx +++ b/apps/spreadsheeteditor/mobile/src/view/Statusbar.jsx @@ -14,7 +14,7 @@ const StatusbarView = inject('sheets')(observer(props => { const isAndroid = Device.android; const isPhone = Device.isPhone; const { sheets } = props; - const hiddenSheets = sheets.hiddensheets; + const hiddenSheets = sheets.hiddenWorksheets(); const getTabClassList = model => `tab ${model.active ? 'active' : ''} ${model.locked ? 'locked' : ''}`; // const $boxTabs = $$('.sheet-tabs'); // const $statusBar = $$('.statusbar'); From fe684e0edbde74f6914fcd879846b46f28d537b0 Mon Sep 17 00:00:00 2001 From: SergeyEzhin Date: Tue, 30 Mar 2021 15:17:24 +0300 Subject: [PATCH 03/43] [SSE mobile] Corrected highlighting tabs --- .../mobile/src/controller/Statusbar.jsx | 87 +++++++++---------- .../mobile/src/less/statusbar.less | 2 +- .../mobile/src/view/Statusbar.jsx | 29 ++++++- 3 files changed, 70 insertions(+), 48 deletions(-) diff --git a/apps/spreadsheeteditor/mobile/src/controller/Statusbar.jsx b/apps/spreadsheeteditor/mobile/src/controller/Statusbar.jsx index 6fdaae007..3531b7d36 100644 --- a/apps/spreadsheeteditor/mobile/src/controller/Statusbar.jsx +++ b/apps/spreadsheeteditor/mobile/src/controller/Statusbar.jsx @@ -10,7 +10,6 @@ const Statusbar = inject('sheets', 'storeAppOptions', 'users')(props => { const {sheets, storeAppOptions, users} = props; const {t} = useTranslation(); const _t = t('Statusbar', {returnObjects: true}); - // console.log(props); let isEdit = storeAppOptions.isEdit; let isDisconnected = users.isDisconnected; @@ -18,7 +17,7 @@ const Statusbar = inject('sheets', 'storeAppOptions', 'users')(props => { useEffect(() => { const onDocumentReady = () => { const api = Common.EditorApi.get(); - api.asc_registerCallback('asc_onUpdateTabColor', onApiUpdateTabColor); + // api.asc_registerCallback('asc_onUpdateTabColor', onApiUpdateTabColor); api.asc_registerCallback('asc_onWorkbookLocked', onWorkbookLocked); api.asc_registerCallback('asc_onWorksheetLocked', onWorksheetLocked); api.asc_registerCallback('asc_onSheetsChanged', onApiSheetsChanged); @@ -44,7 +43,7 @@ const Statusbar = inject('sheets', 'storeAppOptions', 'users')(props => { Common.Notifications.off('document:ready', onApiSheetsChanged); const api = Common.EditorApi.get(); - api.asc_unregisterCallback('asc_onUpdateTabColor', onApiUpdateTabColor); + // api.asc_unregisterCallback('asc_onUpdateTabColor', onApiUpdateTabColor); api.asc_unregisterCallback('asc_onWorkbookLocked', onWorkbookLocked); api.asc_unregisterCallback('asc_onWorksheetLocked', onWorksheetLocked); api.asc_unregisterCallback('asc_onSheetsChanged', onApiSheetsChanged); @@ -63,7 +62,8 @@ const Statusbar = inject('sheets', 'storeAppOptions', 'users')(props => { }; const onWorksheetLocked = (index, locked) => { - let model = sheets.sheets.find(sheet => sheet.index === index); + // let model = sheets.sheets.find(sheet => sheet.index === index); + let model = sheets.at(index); if(model && model.locked != locked) model.locked = locked; }; @@ -87,58 +87,57 @@ const Statusbar = inject('sheets', 'storeAppOptions', 'users')(props => { color : api.asc_getWorksheetTabColor(i) }; - // (api.asc_isWorksheetHidden(i) ? hiddentems : items).push(tab); items.push(tab); } sheets.resetSheets(items); - updateTabsColors(); + // updateTabsColors(); }; - const loadTabColor = sheetindex => { - const api = Common.EditorApi.get(); - let tab = sheets.sheets.find(sheet => sheet.index === sheetindex); + // const loadTabColor = sheetindex => { + // const api = Common.EditorApi.get(); + // let tab = sheets.sheets.find(sheet => sheet.index === sheetindex); - if (tab) { - setTabLineColor(tab, api.asc_getWorksheetTabColor(sheetindex)); - } + // if (tab) { + // setTabLineColor(tab, api.asc_getWorksheetTabColor(sheetindex)); + // } - }; + // }; - const onApiUpdateTabColor = index => { - loadTabColor(index); - }; + // const onApiUpdateTabColor = index => { + // loadTabColor(index); + // }; - const setTabLineColor = (tab, color) => { - console.log(tab); - if (tab) { - if (null !== color) { - color = '#' + Common.Utils.ThemeColor.getHexColor(color.get_r(), color.get_g(), color.get_b()); - } else { - color = ''; - } + // const setTabLineColor = (tab, color) => { + // console.log(color); + // if (tab) { + // if (null !== color) { + // color = '#' + Common.Utils.ThemeColor.getHexColor(color.get_r(), color.get_g(), color.get_b()); + // } else { + // color = ''; + // } - if (color.length) { - if (!tab.active) { - color = '0px 4px 0 ' + Common.Utils.RGBColor(color).toRGBA(0.7) + ' inset'; - } else { - color = '0px 4px 0 ' + color + ' inset'; - } + // if (color.length) { + // if (!tab.active) { + // color = '0px 4px 0 ' + Common.Utils.RGBColor(color).toRGBA(0.7) + ' inset'; + // } else { + // color = '0px 4px 0 ' + color + ' inset'; + // } - $$('.sheet-tabs .tab a').eq(tab.index).css('box-shadow', color); - } else { - $$('.sheet-tabs .tab a').eq(tab.index).css('box-shadow', ''); - } - } - }; + // $$('.sheet-tabs .tab a').eq(tab.index).css('box-shadow', color); + // } else { + // $$('.sheet-tabs .tab a').eq(tab.index).css('box-shadow', ''); + // } + // } + // }; - const updateTabsColors = () => { - const api = Common.EditorApi.get(); + // const updateTabsColors = () => { + // const api = Common.EditorApi.get(); - sheets.sheets.forEach(model => { - setTabLineColor(model, api.asc_getWorksheetTabColor(model.index)); - }); - }; + // sheets.sheets.forEach(model => { + // setTabLineColor(model, api.asc_getWorksheetTabColor(model.index)); + // }); + // }; const onTabClicked = i => { const model = sheets.at(i); @@ -195,7 +194,7 @@ const Statusbar = inject('sheets', 'storeAppOptions', 'users')(props => { } else { f7.popover.close('#idx-tab-context-menu-popover', false); onTabClicked(i); - Common.Notifications.trigger('sheet:active', index); + // Common.Notifications.trigger('sheet:active', index); } }; @@ -305,7 +304,7 @@ const Statusbar = inject('sheets', 'storeAppOptions', 'users')(props => { } else { f7.popover.close('#idx-hidden-sheets-popover'); api['asc_showWorksheet'](index); - loadTabColor(index); + // loadTabColor(index); } }; diff --git a/apps/spreadsheeteditor/mobile/src/less/statusbar.less b/apps/spreadsheeteditor/mobile/src/less/statusbar.less index d0349cf0a..40fe15ce9 100644 --- a/apps/spreadsheeteditor/mobile/src/less/statusbar.less +++ b/apps/spreadsheeteditor/mobile/src/less/statusbar.less @@ -45,7 +45,7 @@ > li { a { font-size: 12px; - padding: 0 20px 0; + padding: 0 10px 0; line-height: @statusbar-height; color: @text-normal; height: 100%; diff --git a/apps/spreadsheeteditor/mobile/src/view/Statusbar.jsx b/apps/spreadsheeteditor/mobile/src/view/Statusbar.jsx index 088994c5f..c4915bbba 100644 --- a/apps/spreadsheeteditor/mobile/src/view/Statusbar.jsx +++ b/apps/spreadsheeteditor/mobile/src/view/Statusbar.jsx @@ -15,7 +15,29 @@ const StatusbarView = inject('sheets')(observer(props => { const isPhone = Device.isPhone; const { sheets } = props; const hiddenSheets = sheets.hiddenWorksheets(); + const allSheets = sheets.sheets; const getTabClassList = model => `tab ${model.active ? 'active' : ''} ${model.locked ? 'locked' : ''}`; + + const getTabColor = model => { + let color = model.color; + + if (color) { + color = '#' + Common.Utils.ThemeColor.getHexColor(color.get_r(), color.get_g(), color.get_b()); + } else { + color = ''; + } + + if (color.length) { + if (!model.active) { + color = '0px 4px 0 ' + Common.Utils.RGBColor(color).toRGBA(0.7) + ' inset'; + } else { + color = '0px 4px 0 ' + color + ' inset'; + } + } + + return color; + } + // const $boxTabs = $$('.sheet-tabs'); // const $statusBar = $$('.statusbar'); @@ -102,11 +124,12 @@ const StatusbarView = inject('sheets')(observer(props => {
From dd3b5fafe0d651b7e91b790f189dbeb531f6d3f7 Mon Sep 17 00:00:00 2001 From: SergeyEzhin Date: Tue, 30 Mar 2021 17:51:53 +0300 Subject: [PATCH 04/43] [SSE mobile] Corrected some things --- apps/common/mobile/lib/view/Search.jsx | 4 ++-- apps/documenteditor/mobile/src/controller/edit/EditText.jsx | 2 +- .../mobile/src/controller/edit/EditText.jsx | 2 +- .../spreadsheeteditor/mobile/src/controller/edit/EditCell.jsx | 2 +- .../spreadsheeteditor/mobile/src/controller/edit/EditText.jsx | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/common/mobile/lib/view/Search.jsx b/apps/common/mobile/lib/view/Search.jsx index 17e4cfb4d..ae026d894 100644 --- a/apps/common/mobile/lib/view/Search.jsx +++ b/apps/common/mobile/lib/view/Search.jsx @@ -272,13 +272,13 @@ class SearchView extends Component {
- {this.changeSearchQuery(e.target.value)}} /> {isIos ? : null}
- {this.changeReplaceQuery(e.target.value)}} /> {isIos ? : null} diff --git a/apps/documenteditor/mobile/src/controller/edit/EditText.jsx b/apps/documenteditor/mobile/src/controller/edit/EditText.jsx index 271741f52..922458b4b 100644 --- a/apps/documenteditor/mobile/src/controller/edit/EditText.jsx +++ b/apps/documenteditor/mobile/src/controller/edit/EditText.jsx @@ -18,7 +18,7 @@ class EditTextController extends Component { if (isDecrement) { typeof size === 'undefined' ? api.FontSizeOut() : size = Math.max(1, --size); } else { - typeof size === 'undefined' ? api.FontSizeIn : size = Math.min(100, ++size); + typeof size === 'undefined' ? api.FontSizeIn : size = Math.min(300, ++size); } if (typeof size !== 'undefined') { api.put_TextPrFontSize(size); diff --git a/apps/presentationeditor/mobile/src/controller/edit/EditText.jsx b/apps/presentationeditor/mobile/src/controller/edit/EditText.jsx index 2b9ce3ae1..01ddd0801 100644 --- a/apps/presentationeditor/mobile/src/controller/edit/EditText.jsx +++ b/apps/presentationeditor/mobile/src/controller/edit/EditText.jsx @@ -132,7 +132,7 @@ class EditTextController extends Component { if (isDecrement) { typeof size === 'undefined' ? api.FontSizeOut() : size = Math.max(1, --size); } else { - typeof size === 'undefined' ? api.FontSizeIn : size = Math.min(100, ++size); + typeof size === 'undefined' ? api.FontSizeIn : size = Math.min(300, ++size); } if (typeof size !== 'undefined') { api.put_TextPrFontSize(size); diff --git a/apps/spreadsheeteditor/mobile/src/controller/edit/EditCell.jsx b/apps/spreadsheeteditor/mobile/src/controller/edit/EditCell.jsx index 22c23b7ae..b0d7bd9b7 100644 --- a/apps/spreadsheeteditor/mobile/src/controller/edit/EditCell.jsx +++ b/apps/spreadsheeteditor/mobile/src/controller/edit/EditCell.jsx @@ -47,7 +47,7 @@ class EditCellController extends Component { if (isDecrement) { typeof size === 'undefined' ? api.asc_decreaseFontSize() : size = Math.max(1, --size); } else { - typeof size === 'undefined' ? api.asc_increaseFontSize() : size = Math.min(100, ++size); + typeof size === 'undefined' ? api.asc_increaseFontSize() : size = Math.min(409, ++size); } if (typeof size !== 'undefined') { diff --git a/apps/spreadsheeteditor/mobile/src/controller/edit/EditText.jsx b/apps/spreadsheeteditor/mobile/src/controller/edit/EditText.jsx index 5be6e60dd..3aac994dd 100644 --- a/apps/spreadsheeteditor/mobile/src/controller/edit/EditText.jsx +++ b/apps/spreadsheeteditor/mobile/src/controller/edit/EditText.jsx @@ -69,7 +69,7 @@ class EditTextController extends Component { if (isDecrement) { typeof size === 'undefined' ? api.asc_decreaseFontSize() : size = Math.max(1, --size); } else { - typeof size === 'undefined' ? api.asc_increaseFontSize() : size = Math.min(100, ++size); + typeof size === 'undefined' ? api.asc_increaseFontSize() : size = Math.min(409, ++size); } if (typeof size !== 'undefined') { From 0bbd65fadd1917c1ab352ec3038514b48d3de05a Mon Sep 17 00:00:00 2001 From: SergeyEzhin Date: Thu, 1 Apr 2021 01:23:00 +0300 Subject: [PATCH 05/43] [PE mobile] Bug 47909, Bug 48110 --- apps/common/mobile/resources/less/common.less | 1 + apps/presentationeditor/mobile/locale/en.json | 3 ++- apps/presentationeditor/mobile/src/view/add/Add.jsx | 12 +++++++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/common/mobile/resources/less/common.less b/apps/common/mobile/resources/less/common.less index ad82957bc..428a99e1b 100644 --- a/apps/common/mobile/resources/less/common.less +++ b/apps/common/mobile/resources/less/common.less @@ -192,6 +192,7 @@ height: 38px; margin-top: 14px; background-image: url(../img/themes/themes.png); + display: block; } .item-theme.active:before { content: ''; diff --git a/apps/presentationeditor/mobile/locale/en.json b/apps/presentationeditor/mobile/locale/en.json index b90038922..444a910fc 100644 --- a/apps/presentationeditor/mobile/locale/en.json +++ b/apps/presentationeditor/mobile/locale/en.json @@ -273,7 +273,8 @@ "textSearch": "Search", "textCaseSensitive": "Case Sensitive", "textHighlight": "Highlight Results", - "textNoTextFound": "Text not Found" + "textNoTextFound": "Text not Found", + "textSelectObjectToEdit": "Select object to edit" } }, "Common": { diff --git a/apps/presentationeditor/mobile/src/view/add/Add.jsx b/apps/presentationeditor/mobile/src/view/add/Add.jsx index d9483113f..9608afc93 100644 --- a/apps/presentationeditor/mobile/src/view/add/Add.jsx +++ b/apps/presentationeditor/mobile/src/view/add/Add.jsx @@ -73,9 +73,11 @@ const AddLayoutContent = ({ tabs }) => { const AddTabs = props => { const { t } = useTranslation(); const _t = t('View.Add', {returnObjects: true}); + const api = Common.EditorApi.get(); + const countPages = api.getCountPages(); const showPanels = props.showPanels; const tabs = []; - if (!showPanels) { + if (!showPanels && countPages) { tabs.push({ caption: _t.textSlide, id: 'add-slide', @@ -101,6 +103,14 @@ const AddTabs = props => { component: }); } + if(!showPanels && !countPages) { + tabs.push({ + caption: _t.textSlide, + id: 'add-slide', + icon: 'icon-add-slide', + component: + }); + } if (showPanels && showPanels === 'link') { tabs.push({ caption: _t.textAddLink, From 5d68405408b3978b2ccfdeadf0da23498b440451 Mon Sep 17 00:00:00 2001 From: SergeyEzhin Date: Fri, 2 Apr 2021 16:16:23 +0300 Subject: [PATCH 06/43] [DE SSE mobile] Bug 48776 --- apps/common/mobile/resources/less/common.less | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/apps/common/mobile/resources/less/common.less b/apps/common/mobile/resources/less/common.less index 428a99e1b..1160e4d26 100644 --- a/apps/common/mobile/resources/less/common.less +++ b/apps/common/mobile/resources/less/common.less @@ -84,6 +84,12 @@ } } +.dialog { + .content-block { + padding: 0; + } +} + .about { .content-block { margin: 0 auto 15px; @@ -696,6 +702,24 @@ input[type="number"]::-webkit-inner-spin-button { } +.picker-3d { + .picker-item { + padding: 0; + text-align: left; + font-size: 16px; + span { + padding: 0; + } + } +} + +.picker-center-highlight { + width: 100%; + left: 0; + right: 0; +} + + From bc7713368a787e01a0ce93a2d7956c77c762e1c5 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Wed, 7 Apr 2021 20:15:09 +0300 Subject: [PATCH 07/43] [DE mobile] Add preloader for long actions --- apps/common/mobile/utils/IrregularStack.js | 50 ++++++ apps/documenteditor/mobile/locale/en.json | 36 +++- .../mobile/src/controller/Main.jsx | 162 ++++++++++++++++++ 3 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 apps/common/mobile/utils/IrregularStack.js diff --git a/apps/common/mobile/utils/IrregularStack.js b/apps/common/mobile/utils/IrregularStack.js new file mode 100644 index 000000000..c252cad0e --- /dev/null +++ b/apps/common/mobile/utils/IrregularStack.js @@ -0,0 +1,50 @@ + +export default class IrregularStack { + constructor (config) { + this._stack = []; + + const _config = config || {}; + this._strongCompare = _config.strongCompare || this._compare; + this._weakCompare = _config.weakCompare || this._compare; + } + + _compare (obj1, obj2) { + if (typeof obj1 === 'object' && typeof obj2 === 'object' && window.JSON) + return window.JSON.stringify(obj1) === window.JSON.stringify(obj2); + return obj1 === obj2; + }; + + _indexOf (obj, compare) { + for (let i = this._stack.length - 1; i >= 0; i--) { + if (compare(this._stack[i], obj)) + return i; + } + return -1; + } + + push (obj) { + this._stack.push(obj); + } + + pop (obj) { + const index = this._indexOf(obj, this._strongCompare); + if (index !== -1) { + const removed = this._stack.splice(index, 1); + return removed[0]; + } + return undefined; + } + + get (obj) { + const index = this._indexOf(obj, this._weakCompare); + if (index !== -1) { + return this._stack[index]; + } + return undefined; + } + + exist (obj) { + return !(this._indexOf(obj, this._strongCompare) < 0); + } + +} \ No newline at end of file diff --git a/apps/documenteditor/mobile/locale/en.json b/apps/documenteditor/mobile/locale/en.json index e2d292591..8c10c061a 100644 --- a/apps/documenteditor/mobile/locale/en.json +++ b/apps/documenteditor/mobile/locale/en.json @@ -44,7 +44,41 @@ "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" + "textClose": "Close", + + "openTitleText": "Opening Document", + "openTextText": "Opening document...", + "saveTitleText": "Saving Document", + "saveTextText": "Saving document...", + "loadFontsTitleText": "Loading Data", + "loadFontsTextText": "Loading data...", + "loadImagesTitleText": "Loading Images", + "loadImagesTextText": "Loading images...", + "loadFontTitleText": "Loading Data", + "loadFontTextText": "Loading data...", + "loadImageTitleText": "Loading Image", + "loadImageTextText": "Loading image...", + "downloadTitleText": "Downloading Document", + "downloadTextText": "Downloading document...", + "printTitleText": "Printing Document", + "printTextText": "Printing document...", + "uploadImageTitleText": "Uploading Image", + "uploadImageTextText": "Uploading image...", + "applyChangesTitleText": "Loading Data", + "applyChangesTextText": "Loading data...", + "savePreparingText": "Preparing to save", + "savePreparingTitle": "Preparing to save. Please wait...", + "mailMergeLoadFileText": "Loading Data Source...", + "mailMergeLoadFileTitle": "Loading Data Source", + "downloadMergeTitle": "Downloading", + "downloadMergeText": "Downloading...", + "sendMergeTitle": "Sending Merge", + "sendMergeText": "Sending Merge...", + "waitText": "Please, wait...", + "txtEditingMode": "Set editing mode...", + "loadingDocumentTitleText": "Loading document", + "loadingDocumentTextText": "Loading document...", + "textLoadingDocument": "Loading document" }, "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 2c4e5b91f..047c69ee4 100644 --- a/apps/documenteditor/mobile/src/controller/Main.jsx +++ b/apps/documenteditor/mobile/src/controller/Main.jsx @@ -4,6 +4,7 @@ import {inject} from "mobx-react"; import { f7 } from "framework7-react"; import { withTranslation } from 'react-i18next'; import { LocalStorage } from '../../../../common/mobile/utils/LocalStorage'; +import IrregularStack from '../../../../common/mobile/utils/IrregularStack'; import CollaborationController from '../../../../common/mobile/lib/controller/collaboration/Collaboration.jsx'; import {InitReviewController as ReviewController} from '../../../../common/mobile/lib/controller/collaboration/Review.jsx'; import { onAdvancedOptions } from './settings/Download.jsx'; @@ -35,8 +36,15 @@ class MainController extends Component { licenseType: false }; + this.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;} + }); + const { t } = this.props; this._t = t('Main', {returnObjects:true}); + + this.LoadingDocument = -256; } initSdk() { @@ -181,6 +189,9 @@ class MainController extends Component { Common.Notifications.trigger('document:ready'); this._isDocReady = true; + + f7.dialog.close(this.loadMask.el); + this.onLongActionEnd(Asc.c_oAscAsyncActionType['BlockInteraction'], this.LoadingDocument); }; const _process_array = (array, fn) => { @@ -388,6 +399,10 @@ class MainController extends Component { } bindEvents() { + this.api.asc_registerCallback('asc_onStartAction', this.onLongActionBegin.bind(this)); + this.api.asc_registerCallback('asc_onEndAction', this.onLongActionEnd.bind(this)); + this.api.asc_registerCallback('asc_onOpenDocumentProgress', this.onOpenDocument.bind(this)); + this.api.asc_registerCallback('asc_onSendThemeColors', (colors, standart_colors) => { Common.Utils.ThemeColor.setColors(colors, standart_colors); }); @@ -519,6 +534,153 @@ class MainController extends Component { }); } + onLongActionBegin (type, id) { + const action = {id: id, type: type}; + this.stackLongActions.push(action); + this.setLongActionView(action); + } + + onLongActionEnd (type, id) { + let action = {id: id, type: type}; + this.stackLongActions.pop(action); + + //this.updateWindowTitle(true); + + action = this.stackLongActions.get({type: Asc.c_oAscAsyncActionType.Information}); + + if (action) { + this.setLongActionView(action) + } + + action = this.stackLongActions.get({type: Asc.c_oAscAsyncActionType.BlockInteraction}); + + if (action) { + this.setLongActionView(action) + } else { + this.loadMask.el && this.loadMask.el.classList.contains('modal-in') && f7.dialog.close(this.loadMask.el); + } + } + + setLongActionView (action) { + const _t = this._t; + let title = ''; + let text = ''; + switch (action.id) { + case Asc.c_oAscAsyncAction['Open']: + title = _t.openTitleText; + text = _t.openTextText; + break; + + case Asc.c_oAscAsyncAction['Save']: + title = _t.saveTitleText; + text = _t.saveTextText; + break; + + case Asc.c_oAscAsyncAction['LoadDocumentFonts']: + 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['MailMergeLoadFile']: + title = _t.mailMergeLoadFileText; + text = _t.mailMergeLoadFileTitle; + break; + + case Asc.c_oAscAsyncAction['DownloadMerge']: + title = _t.downloadMergeTitle; + text = _t.downloadMergeText; + break; + + case Asc.c_oAscAsyncAction['SendMailMerge']: + title = _t.sendMergeTitle; + text = _t.sendMergeText; + 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']) { + return; + } + + if (this.loadMask && this.loadMask.el && this.loadMask.el.classList.contains('modal-in')) { + this.loadMask.el.getElementsByClassName('dialog-title')[0].innerHTML = title; + } else { + this.loadMask = f7.dialog.preloader(title); + } + } + + } + + onOpenDocument (progress) { + if (this.loadMask && this.loadMask.el) { + const $title = this.loadMask.el.getElementsByClassName('dialog-title')[0]; + const proc = (progress.asc_getCurrentFont() + progress.asc_getCurrentImage())/(progress.asc_getFontsCount() + progress.asc_getImagesCount()); + + $title.innerHTML = `${this._t.textLoadingDocument}: ${Math.min(Math.round(proc * 100), 100)}%`; + } + } + render() { return ( From 94b4ebc18c4f289ece8f58d8f330a3272dbec99c Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Thu, 8 Apr 2021 17:25:44 +0300 Subject: [PATCH 08/43] [DE mobile] refactoring for patch code --- .../mobile/src/store/focusObjects.js | 26 ++----------------- 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/apps/documenteditor/mobile/src/store/focusObjects.js b/apps/documenteditor/mobile/src/store/focusObjects.js index b9a9f4e16..7b75f2cec 100644 --- a/apps/documenteditor/mobile/src/store/focusObjects.js +++ b/apps/documenteditor/mobile/src/store/focusObjects.js @@ -1,4 +1,5 @@ import {action, observable, computed, makeObservable} from 'mobx'; +import EditorUIController from '../lib/patch' export class storeFocusObjects { constructor() { @@ -27,30 +28,7 @@ export class storeFocusObjects { } get settings() { - const _settings = []; - for (let object of this._focusObjects) { - let type = object.get_ObjectType(); - if (Asc.c_oAscTypeSelectElement.Paragraph === type) { - _settings.push('text', 'paragraph'); - } else if (Asc.c_oAscTypeSelectElement.Table === type) { - _settings.push('table'); - } else if (Asc.c_oAscTypeSelectElement.Image === type) { - if (object.get_ObjectValue().get_ChartProperties()) { - // Exclude shapes if chart exist - let si = _settings.indexOf('shape'); - si < 0 ? _settings.push('chart') : _settings.splice(si,1,'chart'); - } else if (object.get_ObjectValue().get_ShapeProperties() && !_settings.includes('chart')) { - _settings.push('shape'); - } else { - _settings.push('image'); - } - } else if (Asc.c_oAscTypeSelectElement.Hyperlink === type) { - _settings.push('hyperlink'); - } else if (Asc.c_oAscTypeSelectElement.Header === type) { - _settings.push('header'); - } - } - return _settings.filter((value, index, self) => self.indexOf(value) === index); + return EditorUIController.filterFocusObjects(this._focusObjects); } get headerType() { From 6c628b62ec6e8292c0731388563e1c8eac50d6f6 Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Thu, 8 Apr 2021 17:26:59 +0300 Subject: [PATCH 09/43] [DE mobile] added missed functions --- apps/documenteditor/mobile/src/lib/patch.jsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/documenteditor/mobile/src/lib/patch.jsx b/apps/documenteditor/mobile/src/lib/patch.jsx index c6788a651..d3d114743 100644 --- a/apps/documenteditor/mobile/src/lib/patch.jsx +++ b/apps/documenteditor/mobile/src/lib/patch.jsx @@ -11,4 +11,10 @@ EditorUIController.getToolbarOptions = () => { return null }; +EditorUIController.initFonts = () => null; +EditorUIController.initEditorStyles = () => null; +EditorUIController.initFocusObjects = () => null; +EditorUIController.filterFocusObjects = () => []; +EditorUIController.initTableTemplates = () => null; + export default EditorUIController; From ee15cf025dd64fe0f48eba015c7bdcea0446a38b Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Thu, 8 Apr 2021 17:28:02 +0300 Subject: [PATCH 10/43] [DE mobile] refactoring in Main controller --- .../mobile/src/controller/Main.jsx | 49 ++++--------------- 1 file changed, 9 insertions(+), 40 deletions(-) diff --git a/apps/documenteditor/mobile/src/controller/Main.jsx b/apps/documenteditor/mobile/src/controller/Main.jsx index 047c69ee4..38d679cce 100644 --- a/apps/documenteditor/mobile/src/controller/Main.jsx +++ b/apps/documenteditor/mobile/src/controller/Main.jsx @@ -216,6 +216,9 @@ class MainController extends Component { 'translate': t('Main.SDK', {returnObjects:true}) }); + Common.Notifications.trigger('engineCreated', this.api); + Common.EditorApi = {get: () => this.api}; + this.appOptions = {}; this.bindEvents(); @@ -223,9 +226,6 @@ class MainController extends Component { // Common.Gateway.on('showmessage', _.bind(me.onExternalMessage, me)); Common.Gateway.on('opendocument', loadDocument); Common.Gateway.appReady(); - - Common.Notifications.trigger('engineCreated', this.api); - Common.EditorApi = {get: () => this.api}; }, error => { console.log('promise failed ' + error); }); @@ -414,34 +414,12 @@ class MainController extends Component { this.api.asc_registerCallback('asc_onDocSize', (w, h) => { storeDocumentSettings.changeDocSize(w, h); }); - const storeFocusObjects = this.props.storeFocusObjects; - this.api.asc_registerCallback('asc_onFocusObject', objects => { - storeFocusObjects.resetFocusObjects(objects); - }); //text settings const storeTextSettings = this.props.storeTextSettings; - this.api.asc_registerCallback('asc_onInitEditorFonts', (fonts, select) => { - storeTextSettings.initEditorFonts(fonts, select); - }); - this.api.asc_registerCallback('asc_onFontFamily', (font) => { - storeTextSettings.resetFontName(font); - }); - this.api.asc_registerCallback('asc_onFontSize', (size) => { - storeTextSettings.resetFontSize(size); - }); - this.api.asc_registerCallback('asc_onBold', (isBold) => { - storeTextSettings.resetIsBold(isBold); - }); - this.api.asc_registerCallback('asc_onItalic', (isItalic) => { - storeTextSettings.resetIsItalic(isItalic); - }); - this.api.asc_registerCallback('asc_onUnderline', (isUnderline) => { - storeTextSettings.resetIsUnderline(isUnderline); - }); - this.api.asc_registerCallback('asc_onStrikeout', (isStrikeout) => { - storeTextSettings.resetIsStrikeout(isStrikeout); - }); + EditorUIController.initFonts(storeTextSettings); + EditorUIController.initFocusObjects(this.props.storeFocusObjects); + this.api.asc_registerCallback('asc_onVerticalAlign', (typeBaseline) => { storeTextSettings.resetTypeBaseline(typeBaseline); }); @@ -473,23 +451,14 @@ class MainController extends Component { }); //paragraph settings - this.api.asc_setParagraphStylesSizes(330, 38); - const storeParagraphSettings = this.props.storeParagraphSettings; - this.api.asc_registerCallback('asc_onInitEditorStyles', (styles) => { - storeParagraphSettings.initEditorStyles(styles); - }); - this.api.asc_registerCallback('asc_onParaStyleName', (name) => { - storeParagraphSettings.changeParaStyleName(name); - }); + EditorUIController.initEditorStyles(this.props.storeParagraphSettings); //table settings - const storeTableSettings = this.props.storeTableSettings; - this.api.asc_registerCallback('asc_onInitTableTemplates', (templates) => { - storeTableSettings.initTableTemplates(templates); - }); + EditorUIController.initTableTemplates(this.props.storeTableSettings); //chart settings const storeChartSettings = this.props.storeChartSettings; + const storeFocusObjects = this.props.storeFocusObjects; this.api.asc_registerCallback('asc_onUpdateChartStyles', () => { if (storeFocusObjects.chartObject && storeFocusObjects.chartObject.get_ChartProperties()) { storeChartSettings.updateChartStyles(this.api.asc_getChartPreviews(storeFocusObjects.chartObject.get_ChartProperties().getType())); From c3e14f5f12c990187e83c34514f68a4e31013092 Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Thu, 8 Apr 2021 17:54:03 +0300 Subject: [PATCH 11/43] [deploy] changed script for release build --- vendor/framework7-react/build/webpack.config.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/vendor/framework7-react/build/webpack.config.js b/vendor/framework7-react/build/webpack.config.js index 66d070865..96c99cba7 100644 --- a/vendor/framework7-react/build/webpack.config.js +++ b/vendor/framework7-react/build/webpack.config.js @@ -168,9 +168,11 @@ module.exports = { ...(env === 'production' ? [ new CssMinimizerPlugin({ - processorOptions: { - safe: true, - map: { inline: false }, + minimizerOptions: { + processorOptions: { + safe: true, + map: { inline: false }, + }, }, }), new webpack.optimize.ModuleConcatenationPlugin(), From 3bcd2a55a78f47529a2b9db4cc9b6bf4da9c04e5 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Thu, 8 Apr 2021 18:34:57 +0300 Subject: [PATCH 12/43] [DE mobile] Add error controller --- apps/documenteditor/mobile/locale/en.json | 45 +++- .../mobile/src/controller/Error.jsx | 227 ++++++++++++++++++ .../mobile/src/controller/Main.jsx | 72 +++++- .../mobile/src/store/appOptions.js | 10 +- apps/documenteditor/mobile/src/view/app.jsx | 2 + 5 files changed, 353 insertions(+), 3 deletions(-) create mode 100644 apps/documenteditor/mobile/src/controller/Error.jsx diff --git a/apps/documenteditor/mobile/locale/en.json b/apps/documenteditor/mobile/locale/en.json index 8c10c061a..3fd29bce3 100644 --- a/apps/documenteditor/mobile/locale/en.json +++ b/apps/documenteditor/mobile/locale/en.json @@ -78,7 +78,50 @@ "txtEditingMode": "Set editing mode...", "loadingDocumentTitleText": "Loading document", "loadingDocumentTextText": "Loading document...", - "textLoadingDocument": "Loading document" + "textLoadingDocument": "Loading document", + + "errorProcessSaveResult": "Saving is failed.", + "criticalErrorTitle": "Error", + "warnProcessRightsChange": "You have been denied the right to edit the file.", + "errorAccessDeny": "You are trying to perform an action you do not have rights for.
Please contact your Document Server administrator." + }, + "Error": { + "criticalErrorTitle": "Error", + "unknownErrorText": "Unknown error.", + "convertationTimeoutText": "Convertation timeout exceeded.", + "openErrorText": "An error has occurred while opening the file", + "saveErrorText": "An error has occurred while saving the file", + "downloadErrorText": "Download failed.", + "uploadImageSizeMessage": "Maximium image size limit exceeded.", + "uploadImageExtMessage": "Unknown image format.", + "uploadImageFileCountMessage": "No images uploaded.", + "splitMaxRowsErrorText": "The number of rows must be less than %1", + "splitMaxColsErrorText": "The number of columns must be less than %1", + "splitDividerErrorText": "The number of rows must be a divisor of %1", + "errorKeyEncrypt": "Unknown key descriptor", + "errorKeyExpire": "Key descriptor expired", + "errorUsersExceed": "Count of users was exceed", + "errorViewerDisconnect": "Connection is lost. You can still view the document,
but will not be able to download until the connection is restored and page is reloaded.", + "errorFilePassProtect": "The file is password protected and could not be opened.", + "errorStockChart": "Incorrect row order. To build a stock chart place the data on the sheet in the following order:
opening price, max price, min price, closing price.", + "errorDataRange": "Incorrect data range.", + "errorDatabaseConnection": "External error.
Database connection error. Please, contact support.", + "errorUserDrop": "The file cannot be accessed right now.", + "errorMailMergeLoadFile": "Loading failed", + "errorMailMergeSaveFile": "Merge failed.", + "errorConnectToServer": " The document could not be saved. Please check connection settings or contact your administrator.
When you click the 'OK' button, you will be prompted to download the document.", + "errorBadImageUrl": "Image url is incorrect", + "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.", + "errorDataEncrypted": "Encrypted changes have been received, they cannot be deciphered.", + "errorAccessDeny": "You are trying to perform an action you do not have rights for.
Please contact your Document Server administrator.", + "errorEditingDownloadas": "An error occurred during the work with the document.
Use the 'Download' option to save the file backup copy to your computer hard drive.", + "errorFileSizeExceed": "The file size exceeds the limitation set for your server.
Please contact your Document Server administrator for details.", + "errorUpdateVersionOnDisconnect": "Internet connection has been restored, and the file version has been changed.
Before you can continue working, you need to download the file or copy its content to make sure nothing is lost, and then reload this page.", + "errorDefaultMessage": "Error code: %1", + "criticalErrorExtText": "Press 'OK' to back to document list.", + "notcriticalErrorTitle": "Warning" }, "Toolbar": { "dlgLeaveTitleText": "You leave the application", diff --git a/apps/documenteditor/mobile/src/controller/Error.jsx b/apps/documenteditor/mobile/src/controller/Error.jsx new file mode 100644 index 000000000..ca7d93673 --- /dev/null +++ b/apps/documenteditor/mobile/src/controller/Error.jsx @@ -0,0 +1,227 @@ +import React, { useEffect, useState } from 'react'; +import { inject } from 'mobx-react'; +import { f7 } from 'framework7-react'; +import { useTranslation } from 'react-i18next'; + +const ErrorController = inject('storeAppOptions')(({storeAppOptions}) => { + const {t} = useTranslation(); + const _t = t("Error", { returnObjects: true }); + + useEffect(() => { + Common.Notifications.on('engineCreated', (api) => { + api.asc_registerCallback('asc_onError', onError); + }); + return () => { + const api = Common.EditorApi.get(); + api.asc_unregisterCallback('asc_onError', onError); + } + }); + + const onError = (id, level, errData) => { + if (id === Asc.c_oAscError.ID.LoadingScriptError) { + f7.notification.create({ + title: _t.criticalErrorTitle, + text: _t.criticalErrorTitle, + closeButton: true + }).open(); + return; + } + + //this.hidePreloader(); + //this.onLongActionEnd(Asc.c_oAscAsyncActionType['BlockInteraction'], LoadingDocument); + + 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.errorKeyEncrypt; + break; + + case Asc.c_oAscError.ID.KeyExpire: + config.msg = _t.errorKeyExpire; + 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.DataRangeError: + config.msg = _t.errorDataRange; + 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.MailMergeLoadFile: + config.msg = _t.errorMailMergeLoadFile; + break; + + case Asc.c_oAscError.ID.MailMergeSaveFile: + config.msg = _t.errorMailMergeSaveFile; + 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.EditingError: + config.msg = _t.errorEditingDownloadas; + break; + + case Asc.c_oAscError.ID.ConvertationOpenLimitError: + config.msg = _t.errorFileSizeExceed; + break; + + case Asc.c_oAscError.ID.UpdateVersion: + config.msg = _t.errorUpdateVersionOnDisconnect; + 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 = this.criticalErrorTitle; + + if (storeAppOptions.canBackToFolder && !storeAppOptions.isDesktopApp) { + config.msg += '

' + _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({ + title : config.title, + text : config.msg, + buttons: [ + { + text: 'OK', + onClick: config.callback + } + ] + }).open(); + + Common.component.Analytics.trackEvent('Internal Error', id.toString()); + }; + + return null +}); + +export default ErrorController; \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/controller/Main.jsx b/apps/documenteditor/mobile/src/controller/Main.jsx index 047c69ee4..6e4a3c53d 100644 --- a/apps/documenteditor/mobile/src/controller/Main.jsx +++ b/apps/documenteditor/mobile/src/controller/Main.jsx @@ -16,6 +16,7 @@ import { } from "../../../../common/mobile/lib/controller/collaboration/Comments"; import About from '../../../../common/mobile/lib/view/About'; import EditorUIController from '../lib/patch'; +import ErrorController from "./Error"; @inject( "storeAppOptions", @@ -33,7 +34,8 @@ class MainController extends Component { window.editorType = 'de'; this._state = { - licenseType: false + licenseType: false, + isFromGatewayDownloadAs: false }; this.stackLongActions = new IrregularStack({ @@ -192,6 +194,11 @@ class MainController extends Component { f7.dialog.close(this.loadMask.el); this.onLongActionEnd(Asc.c_oAscAsyncActionType['BlockInteraction'], this.LoadingDocument); + + Common.Gateway.on('processsaveresult', this.onProcessSaveResult.bind(this)); + Common.Gateway.on('processrightschange', this.onProcessRightsChange.bind(this)); + Common.Gateway.on('downloadas', this.onDownloadAs.bind(this)); + Common.Gateway.on('requestclose', this.onRequestClose.bind(this)); }; const _process_array = (array, fn) => { @@ -407,6 +414,8 @@ class MainController extends Component { Common.Utils.ThemeColor.setColors(colors, standart_colors); }); + this.api.asc_registerCallback('asc_onDownloadUrl', this.onDownloadUrl.bind(this)); + const storeDocumentSettings = this.props.storeDocumentSettings; this.api.asc_registerCallback('asc_onPageOrient', isPortrait => { storeDocumentSettings.resetPortrait(isPortrait); @@ -681,9 +690,70 @@ class MainController extends Component { } } + onProcessSaveResult (data) { + this.api.asc_OnSaveEnd(data.result); + + if (data && data.result === false) { + const _t = this._t; + f7.dialog.alert( + (!data.message) ? _t.errorProcessSaveResult : data.message, + _t.criticalErrorTitle + ); + } + } + + 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._t; + f7.dialog.alert( + (!data.message) ? _t.warnProcessRightsChange : data.message, + _t.notcriticalErrorTitle, + () => { appOptions.changeEditingRights(false); } + ); + } + } + } + + onDownloadAs () { + const appOptions = this.props.storeAppOptions; + if ( !appOptions.canDownload && !appOptions.canDownloadOrigin) { + Common.Gateway.reportError(Asc.c_oAscError.ID.AccessDeny, this._t.errorAccessDeny); + return; + } + + this._state.isFromGatewayDownloadAs = true; + const type = /^(?:(pdf|djvu|xps))$/.exec(this.document.fileType); + + if (type && typeof type[1] === 'string') { + this.api.asc_DownloadOrigin(true); + } else { + this.api.asc_DownloadAs(new Asc.asc_CDownloadOptions(Asc.c_oAscFileType.DOCX, true)); + } + } + + onDownloadUrl () { + if (this._state.isFromGatewayDownloadAs) { + Common.Gateway.downloadAs(url); + } + + this._state.isFromGatewayDownloadAs = false; + } + + onRequestClose () { + Common.Gateway.requestClose(); + } + render() { return ( + diff --git a/apps/documenteditor/mobile/src/store/appOptions.js b/apps/documenteditor/mobile/src/store/appOptions.js index a26bc4255..13f521bba 100644 --- a/apps/documenteditor/mobile/src/store/appOptions.js +++ b/apps/documenteditor/mobile/src/store/appOptions.js @@ -8,7 +8,10 @@ export class storeAppOptions { canReview: observable, setConfigOptions: action, setPermissionOptions: action, - setCanViewReview: action + setCanViewReview: action, + + lostEditingRights: observable, + changeEditingRights: action }); } @@ -16,6 +19,11 @@ export class storeAppOptions { canViewComments = false; canReview = false; + lostEditingRights = false; + changeEditingRights (value) { + this.lostEditingRights = value; + } + config = {}; setConfigOptions (config) { this.config = config; diff --git a/apps/documenteditor/mobile/src/view/app.jsx b/apps/documenteditor/mobile/src/view/app.jsx index 9506914c6..b114f32d5 100644 --- a/apps/documenteditor/mobile/src/view/app.jsx +++ b/apps/documenteditor/mobile/src/view/app.jsx @@ -3,6 +3,8 @@ 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 { f7, f7ready } from 'framework7-react'; +import '../../../../common/Analytics.js'; + import '../../../../common/Gateway.js'; import '../../../../common/main/lib/util/utils.js'; From 904e9baf05e0b5524c1ec17e4c85dbef20275ffd Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Thu, 8 Apr 2021 21:00:44 +0300 Subject: [PATCH 13/43] [DE mobile] Long action handler moved to a separate controller --- apps/documenteditor/mobile/locale/en.json | 69 +++--- .../mobile/src/controller/Error.jsx | 7 +- .../mobile/src/controller/LongActions.jsx | 205 ++++++++++++++++++ .../mobile/src/controller/Main.jsx | 169 +-------------- 4 files changed, 251 insertions(+), 199 deletions(-) create mode 100644 apps/documenteditor/mobile/src/controller/LongActions.jsx diff --git a/apps/documenteditor/mobile/locale/en.json b/apps/documenteditor/mobile/locale/en.json index 3fd29bce3..c522a961a 100644 --- a/apps/documenteditor/mobile/locale/en.json +++ b/apps/documenteditor/mobile/locale/en.json @@ -46,40 +46,6 @@ "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", - "openTitleText": "Opening Document", - "openTextText": "Opening document...", - "saveTitleText": "Saving Document", - "saveTextText": "Saving document...", - "loadFontsTitleText": "Loading Data", - "loadFontsTextText": "Loading data...", - "loadImagesTitleText": "Loading Images", - "loadImagesTextText": "Loading images...", - "loadFontTitleText": "Loading Data", - "loadFontTextText": "Loading data...", - "loadImageTitleText": "Loading Image", - "loadImageTextText": "Loading image...", - "downloadTitleText": "Downloading Document", - "downloadTextText": "Downloading document...", - "printTitleText": "Printing Document", - "printTextText": "Printing document...", - "uploadImageTitleText": "Uploading Image", - "uploadImageTextText": "Uploading image...", - "applyChangesTitleText": "Loading Data", - "applyChangesTextText": "Loading data...", - "savePreparingText": "Preparing to save", - "savePreparingTitle": "Preparing to save. Please wait...", - "mailMergeLoadFileText": "Loading Data Source...", - "mailMergeLoadFileTitle": "Loading Data Source", - "downloadMergeTitle": "Downloading", - "downloadMergeText": "Downloading...", - "sendMergeTitle": "Sending Merge", - "sendMergeText": "Sending Merge...", - "waitText": "Please, wait...", - "txtEditingMode": "Set editing mode...", - "loadingDocumentTitleText": "Loading document", - "loadingDocumentTextText": "Loading document...", - "textLoadingDocument": "Loading document", - "errorProcessSaveResult": "Saving is failed.", "criticalErrorTitle": "Error", "warnProcessRightsChange": "You have been denied the right to edit the file.", @@ -123,6 +89,41 @@ "criticalErrorExtText": "Press 'OK' to back to document list.", "notcriticalErrorTitle": "Warning" }, + "LongActions": { + "openTitleText": "Opening Document", + "openTextText": "Opening document...", + "saveTitleText": "Saving Document", + "saveTextText": "Saving document...", + "loadFontsTitleText": "Loading Data", + "loadFontsTextText": "Loading data...", + "loadImagesTitleText": "Loading Images", + "loadImagesTextText": "Loading images...", + "loadFontTitleText": "Loading Data", + "loadFontTextText": "Loading data...", + "loadImageTitleText": "Loading Image", + "loadImageTextText": "Loading image...", + "downloadTitleText": "Downloading Document", + "downloadTextText": "Downloading document...", + "printTitleText": "Printing Document", + "printTextText": "Printing document...", + "uploadImageTitleText": "Uploading Image", + "uploadImageTextText": "Uploading image...", + "applyChangesTitleText": "Loading Data", + "applyChangesTextText": "Loading data...", + "savePreparingText": "Preparing to save", + "savePreparingTitle": "Preparing to save. Please wait...", + "mailMergeLoadFileText": "Loading Data Source...", + "mailMergeLoadFileTitle": "Loading Data Source", + "downloadMergeTitle": "Downloading", + "downloadMergeText": "Downloading...", + "sendMergeTitle": "Sending Merge", + "sendMergeText": "Sending Merge...", + "waitText": "Please, wait...", + "txtEditingMode": "Set editing mode...", + "loadingDocumentTitleText": "Loading document", + "loadingDocumentTextText": "Loading document...", + "textLoadingDocument": "Loading document" + }, "Toolbar": { "dlgLeaveTitleText": "You leave the application", "dlgLeaveMsgText": "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.", diff --git a/apps/documenteditor/mobile/src/controller/Error.jsx b/apps/documenteditor/mobile/src/controller/Error.jsx index ca7d93673..f1fd7074b 100644 --- a/apps/documenteditor/mobile/src/controller/Error.jsx +++ b/apps/documenteditor/mobile/src/controller/Error.jsx @@ -2,8 +2,9 @@ import React, { useEffect, useState } from 'react'; import { inject } from 'mobx-react'; import { f7 } from 'framework7-react'; import { useTranslation } from 'react-i18next'; +import LongActionsController from "./LongActions"; -const ErrorController = inject('storeAppOptions')(({storeAppOptions}) => { +const ErrorController = inject('storeAppOptions')(({storeAppOptions, LoadingDocument}) => { const {t} = useTranslation(); const _t = t("Error", { returnObjects: true }); @@ -27,8 +28,8 @@ const ErrorController = inject('storeAppOptions')(({storeAppOptions}) => { return; } - //this.hidePreloader(); - //this.onLongActionEnd(Asc.c_oAscAsyncActionType['BlockInteraction'], LoadingDocument); + Common.Notifications.trigger('preloader:close'); + Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], LoadingDocument); const api = Common.EditorApi.get(); diff --git a/apps/documenteditor/mobile/src/controller/LongActions.jsx b/apps/documenteditor/mobile/src/controller/LongActions.jsx new file mode 100644 index 000000000..9b9fb6b8f --- /dev/null +++ b/apps/documenteditor/mobile/src/controller/LongActions.jsx @@ -0,0 +1,205 @@ +import React, { Component } from 'react'; +import { inject } from 'mobx-react'; +import { f7 } from 'framework7-react'; +import { withTranslation } from 'react-i18next'; +import IrregularStack from "../../../../common/mobile/utils/IrregularStack"; + +class LongActions extends Component { + constructor(props) { + super(props); + + this.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;} + }); + + this.onLongActionBegin = this.onLongActionBegin.bind(this); + this.onLongActionEnd = this.onLongActionEnd.bind(this); + this.onOpenDocument = this.onOpenDocument.bind(this); + this.closePreloader = this.closePreloader.bind(this); + } + + closePreloader() { + if (this.loadMask.el) { + f7.dialog.close(this.loadMask.el); + } + } + + componentDidMount() { + Common.Notifications.on('engineCreated', (api) => { + api.asc_registerCallback('asc_onStartAction', this.onLongActionBegin); + api.asc_registerCallback('asc_onEndAction', this.onLongActionEnd); + api.asc_registerCallback('asc_onOpenDocumentProgress', this.onOpenDocument); + }); + Common.Notifications.on('preloader:endAction', this.onLongActionEnd); + Common.Notifications.on('preloader:close', this.closePreloader); + } + + componentWillUnmount() { + const api = Common.EditorApi.get(); + api.asc_unregisterCallback('asc_onStartAction', this.onLongActionBegin); + api.asc_unregisterCallback('asc_onEndAction', this.onLongActionEnd); + api.asc_unregisterCallback('asc_onOpenDocumentProgress', this.onOpenDocument); + + Common.Notifications.off('preloader:endAction', this.onLongActionEnd); + Common.Notifications.off('preloader:close', this.closePreloader); + } + + onLongActionBegin (type, id) { + const action = {id: id, type: type}; + this.stackLongActions.push(action); + this.setLongActionView(action); + } + + onLongActionEnd (type, id) { + let action = {id: id, type: type}; + this.stackLongActions.pop(action); + + //this.updateWindowTitle(true); + + action = this.stackLongActions.get({type: Asc.c_oAscAsyncActionType.Information}); + + if (action) { + this.setLongActionView(action) + } + + action = this.stackLongActions.get({type: Asc.c_oAscAsyncActionType.BlockInteraction}); + + if (action) { + this.setLongActionView(action) + } else { + this.loadMask.el && this.loadMask.el.classList.contains('modal-in') && f7.dialog.close(this.loadMask.el); + } + } + + setLongActionView (action) { + const { t } = this.props; + const _t = t("LongActions", { returnObjects: true }); + let title = ''; + let text = ''; + switch (action.id) { + case Asc.c_oAscAsyncAction['Open']: + title = _t.openTitleText; + text = _t.openTextText; + break; + + case Asc.c_oAscAsyncAction['Save']: + title = _t.saveTitleText; + text = _t.saveTextText; + break; + + case Asc.c_oAscAsyncAction['LoadDocumentFonts']: + 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['MailMergeLoadFile']: + title = _t.mailMergeLoadFileText; + text = _t.mailMergeLoadFileTitle; + break; + + case Asc.c_oAscAsyncAction['DownloadMerge']: + title = _t.downloadMergeTitle; + text = _t.downloadMergeText; + break; + + case Asc.c_oAscAsyncAction['SendMailMerge']: + title = _t.sendMergeTitle; + text = _t.sendMergeText; + 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']) { + return; + } + + if (this.loadMask && this.loadMask.el && this.loadMask.el.classList.contains('modal-in')) { + this.loadMask.el.getElementsByClassName('dialog-title')[0].innerHTML = title; + } else { + this.loadMask = f7.dialog.preloader(title); + } + } + + } + + onOpenDocument (progress) { + if (this.loadMask && this.loadMask.el) { + const $title = this.loadMask.el.getElementsByClassName('dialog-title')[0]; + const proc = (progress.asc_getCurrentFont() + progress.asc_getCurrentImage())/(progress.asc_getFontsCount() + progress.asc_getImagesCount()); + + const { t } = this.props; + const _t = t("LongActions", { returnObjects: true }); + $title.innerHTML = `${_t.textLoadingDocument}: ${Math.min(Math.round(proc * 100), 100)}%`; + } + } + + render() { + return null; + } +} + +const LongActionsController = withTranslation()(LongActions); + +export default LongActionsController; \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/controller/Main.jsx b/apps/documenteditor/mobile/src/controller/Main.jsx index d2e87f6a8..07aece297 100644 --- a/apps/documenteditor/mobile/src/controller/Main.jsx +++ b/apps/documenteditor/mobile/src/controller/Main.jsx @@ -4,7 +4,6 @@ import {inject} from "mobx-react"; import { f7 } from "framework7-react"; import { withTranslation } from 'react-i18next'; import { LocalStorage } from '../../../../common/mobile/utils/LocalStorage'; -import IrregularStack from '../../../../common/mobile/utils/IrregularStack'; import CollaborationController from '../../../../common/mobile/lib/controller/collaboration/Collaboration.jsx'; import {InitReviewController as ReviewController} from '../../../../common/mobile/lib/controller/collaboration/Review.jsx'; import { onAdvancedOptions } from './settings/Download.jsx'; @@ -17,6 +16,7 @@ import { import About from '../../../../common/mobile/lib/view/About'; import EditorUIController from '../lib/patch'; import ErrorController from "./Error"; +import LongActionsController from "./LongActions"; @inject( "storeAppOptions", @@ -33,20 +33,15 @@ class MainController extends Component { super(props); window.editorType = 'de'; + this.LoadingDocument = -256; + this._state = { licenseType: false, isFromGatewayDownloadAs: false }; - this.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;} - }); - const { t } = this.props; this._t = t('Main', {returnObjects:true}); - - this.LoadingDocument = -256; } initSdk() { @@ -192,8 +187,8 @@ class MainController extends Component { this._isDocReady = true; - f7.dialog.close(this.loadMask.el); - this.onLongActionEnd(Asc.c_oAscAsyncActionType['BlockInteraction'], this.LoadingDocument); + Common.Notifications.trigger('preloader:close'); + Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], this.LoadingDocument); Common.Gateway.on('processsaveresult', this.onProcessSaveResult.bind(this)); Common.Gateway.on('processrightschange', this.onProcessRightsChange.bind(this)); @@ -406,10 +401,6 @@ class MainController extends Component { } bindEvents() { - this.api.asc_registerCallback('asc_onStartAction', this.onLongActionBegin.bind(this)); - this.api.asc_registerCallback('asc_onEndAction', this.onLongActionEnd.bind(this)); - this.api.asc_registerCallback('asc_onOpenDocumentProgress', this.onOpenDocument.bind(this)); - this.api.asc_registerCallback('asc_onSendThemeColors', (colors, standart_colors) => { Common.Utils.ThemeColor.setColors(colors, standart_colors); }); @@ -512,153 +503,6 @@ class MainController extends Component { }); } - onLongActionBegin (type, id) { - const action = {id: id, type: type}; - this.stackLongActions.push(action); - this.setLongActionView(action); - } - - onLongActionEnd (type, id) { - let action = {id: id, type: type}; - this.stackLongActions.pop(action); - - //this.updateWindowTitle(true); - - action = this.stackLongActions.get({type: Asc.c_oAscAsyncActionType.Information}); - - if (action) { - this.setLongActionView(action) - } - - action = this.stackLongActions.get({type: Asc.c_oAscAsyncActionType.BlockInteraction}); - - if (action) { - this.setLongActionView(action) - } else { - this.loadMask.el && this.loadMask.el.classList.contains('modal-in') && f7.dialog.close(this.loadMask.el); - } - } - - setLongActionView (action) { - const _t = this._t; - let title = ''; - let text = ''; - switch (action.id) { - case Asc.c_oAscAsyncAction['Open']: - title = _t.openTitleText; - text = _t.openTextText; - break; - - case Asc.c_oAscAsyncAction['Save']: - title = _t.saveTitleText; - text = _t.saveTextText; - break; - - case Asc.c_oAscAsyncAction['LoadDocumentFonts']: - 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['MailMergeLoadFile']: - title = _t.mailMergeLoadFileText; - text = _t.mailMergeLoadFileTitle; - break; - - case Asc.c_oAscAsyncAction['DownloadMerge']: - title = _t.downloadMergeTitle; - text = _t.downloadMergeText; - break; - - case Asc.c_oAscAsyncAction['SendMailMerge']: - title = _t.sendMergeTitle; - text = _t.sendMergeText; - 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']) { - return; - } - - if (this.loadMask && this.loadMask.el && this.loadMask.el.classList.contains('modal-in')) { - this.loadMask.el.getElementsByClassName('dialog-title')[0].innerHTML = title; - } else { - this.loadMask = f7.dialog.preloader(title); - } - } - - } - - onOpenDocument (progress) { - if (this.loadMask && this.loadMask.el) { - const $title = this.loadMask.el.getElementsByClassName('dialog-title')[0]; - const proc = (progress.asc_getCurrentFont() + progress.asc_getCurrentImage())/(progress.asc_getFontsCount() + progress.asc_getImagesCount()); - - $title.innerHTML = `${this._t.textLoadingDocument}: ${Math.min(Math.round(proc * 100), 100)}%`; - } - } - onProcessSaveResult (data) { this.api.asc_OnSaveEnd(data.result); @@ -722,7 +566,8 @@ class MainController extends Component { render() { return ( - + + From 8d6ea8f4642ab55b2d748673cc48096ea75a26d9 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Fri, 9 Apr 2021 21:08:13 +0300 Subject: [PATCH 14/43] [DE mobile] Make main controller --- apps/documenteditor/mobile/locale/en.json | 5 +- .../mobile/src/controller/LongActions.jsx | 2 + .../mobile/src/controller/Main.jsx | 110 +++++++++++++++++- .../framework7-react/build/webpack.config.js | 1 + 4 files changed, 111 insertions(+), 7 deletions(-) diff --git a/apps/documenteditor/mobile/locale/en.json b/apps/documenteditor/mobile/locale/en.json index c522a961a..e508cb033 100644 --- a/apps/documenteditor/mobile/locale/en.json +++ b/apps/documenteditor/mobile/locale/en.json @@ -49,7 +49,10 @@ "errorProcessSaveResult": "Saving is failed.", "criticalErrorTitle": "Error", "warnProcessRightsChange": "You have been denied the right to edit the file.", - "errorAccessDeny": "You are trying to perform an action you do not have rights for.
Please contact your Document Server administrator." + "errorAccessDeny": "You are trying to perform an action you do not have rights for.
Please contact your Document Server administrator.", + + "errorUpdateVersion": "The file version has been changed. The page will be reloaded.", + "titleUpdateVersion": "Version changed" }, "Error": { "criticalErrorTitle": "Error", diff --git a/apps/documenteditor/mobile/src/controller/LongActions.jsx b/apps/documenteditor/mobile/src/controller/LongActions.jsx index 9b9fb6b8f..2c2e0f9fb 100644 --- a/apps/documenteditor/mobile/src/controller/LongActions.jsx +++ b/apps/documenteditor/mobile/src/controller/LongActions.jsx @@ -32,6 +32,7 @@ class LongActions extends Component { api.asc_registerCallback('asc_onOpenDocumentProgress', this.onOpenDocument); }); Common.Notifications.on('preloader:endAction', this.onLongActionEnd); + Common.Notifications.on('preloader:beginAction', this.onLongActionBegin); Common.Notifications.on('preloader:close', this.closePreloader); } @@ -42,6 +43,7 @@ class LongActions extends Component { api.asc_unregisterCallback('asc_onOpenDocumentProgress', this.onOpenDocument); Common.Notifications.off('preloader:endAction', this.onLongActionEnd); + Common.Notifications.off('preloader:beginAction', this.onLongActionBegin); Common.Notifications.off('preloader:close', this.closePreloader); } diff --git a/apps/documenteditor/mobile/src/controller/Main.jsx b/apps/documenteditor/mobile/src/controller/Main.jsx index 07aece297..f40f1f1b6 100644 --- a/apps/documenteditor/mobile/src/controller/Main.jsx +++ b/apps/documenteditor/mobile/src/controller/Main.jsx @@ -37,9 +37,12 @@ class MainController extends Component { this._state = { licenseType: false, - isFromGatewayDownloadAs: false + isFromGatewayDownloadAs: false, + isDocModified: false }; + this.defaultTitleText = __APP_TITLE_TEXT__; + const { t } = this.props; this._t = t('Main', {returnObjects:true}); } @@ -178,6 +181,10 @@ class MainController extends Component { }; const onDocumentContentReady = () => { + if (this.props.storeAppOptions.isEdit && this.needToUpdateVersion) { + Common.Notifications.trigger('api:disconnect'); + } + this.applyLicense(); Common.Gateway.documentReady(); @@ -221,11 +228,24 @@ class MainController extends Component { Common.Notifications.trigger('engineCreated', this.api); Common.EditorApi = {get: () => this.api}; + // Set font rendering mode + let value = LocalStorage.getItem("de-settings-fontrender"); + if (value === null) { + value = window.devicePixelRatio > 1 ? '1' : '0'; + } + switch (value) { + case '0': this.api.SetFontRenderingMode(3); break; + case '1': this.api.SetFontRenderingMode(1); break; + case '2': this.api.SetFontRenderingMode(2); break; + } + + Common.Utils.Metric.setCurrentMetric(1); //pt + this.appOptions = {}; this.bindEvents(); Common.Gateway.on('init', loadConfig); - // Common.Gateway.on('showmessage', _.bind(me.onExternalMessage, me)); + Common.Gateway.on('showmessage', this.onExternalMessage.bind(this)); Common.Gateway.on('opendocument', loadDocument); Common.Gateway.appReady(); }, error => { @@ -401,6 +421,11 @@ class MainController extends Component { } bindEvents() { + 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_onDocumentName', this.onDocumentName.bind(this)); + this.api.asc_registerCallback('asc_onPrintUrl', this.onPrintUrl.bind(this)); + this.api.asc_registerCallback('asc_onSendThemeColors', (colors, standart_colors) => { Common.Utils.ThemeColor.setColors(colors, standart_colors); }); @@ -485,10 +510,6 @@ class MainController extends Component { storeDocumentInfo.switchIsLoaded(true); }); - this.api.asc_registerCallback('asc_onDocumentName', (name) => { - // console.log(name); - }); - // Color Schemes this.api.asc_registerCallback('asc_onSendThemeColorSchemes', (arr) => { @@ -563,6 +584,83 @@ class MainController extends Component { Common.Gateway.requestClose(); } + onUpdateVersion (callback) { + const _t = this._t; + + 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); + }); + } + + 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; + } + } + + 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; + } + } + + 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'); + } + } + render() { return ( diff --git a/vendor/framework7-react/build/webpack.config.js b/vendor/framework7-react/build/webpack.config.js index 96c99cba7..f4eca3eba 100644 --- a/vendor/framework7-react/build/webpack.config.js +++ b/vendor/framework7-react/build/webpack.config.js @@ -164,6 +164,7 @@ module.exports = { __PUBLISHER_PHONE__: JSON.stringify('+371 633-99867'), __PUBLISHER_URL__: JSON.stringify('https://www.onlyoffice.com'), __PUBLISHER_NAME__: JSON.stringify('Ascensio System SIA'), + __APP_TITLE_TEXT__: JSON.stringify(process.env.APP_TITLE_TEXT ? process.env.APP_TITLE_TEXT : 'ONLYOFFICE') }), ...(env === 'production' ? [ From 0f76a317068c225ea7319f45f3f9b4eaced90cdc Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Mon, 12 Apr 2021 15:10:14 +0300 Subject: [PATCH 15/43] [DE mobile] Added replacement of company name in translations --- apps/documenteditor/mobile/src/controller/Main.jsx | 12 +++++++++--- vendor/framework7-react/build/webpack.config.js | 3 ++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/apps/documenteditor/mobile/src/controller/Main.jsx b/apps/documenteditor/mobile/src/controller/Main.jsx index f40f1f1b6..bdfc7fcff 100644 --- a/apps/documenteditor/mobile/src/controller/Main.jsx +++ b/apps/documenteditor/mobile/src/controller/Main.jsx @@ -319,6 +319,12 @@ class MainController extends Component { applyLicense () { const _t = this._t; + 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("de-opensource-warning"); @@ -346,9 +352,9 @@ class MainController extends Component { ) { 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; + license = (license===Asc.c_oLicenseResult.Connections) ? warnLicenseExceeded : warnLicenseUsersExceeded; } else { - license = (license === Asc.c_oLicenseResult.ConnectionsOS) ? _t.warnNoLicense : _t.warnNoLicenseUsers; + license = (license === Asc.c_oLicenseResult.ConnectionsOS) ? warnNoLicense : warnNoLicenseUsers; buttons = [{ text: _t.textBuyNow, bold: true, @@ -378,7 +384,7 @@ class MainController extends Component { if (now - value > 86400000) { LocalStorage.setItem("de-license-warning", now); f7.dialog.create({ - title: _t.textNoLicenseTitle, + title: textNoLicenseTitle, text : license, buttons: buttons }).open(); diff --git a/vendor/framework7-react/build/webpack.config.js b/vendor/framework7-react/build/webpack.config.js index f4eca3eba..9149edcf8 100644 --- a/vendor/framework7-react/build/webpack.config.js +++ b/vendor/framework7-react/build/webpack.config.js @@ -164,7 +164,8 @@ module.exports = { __PUBLISHER_PHONE__: JSON.stringify('+371 633-99867'), __PUBLISHER_URL__: JSON.stringify('https://www.onlyoffice.com'), __PUBLISHER_NAME__: JSON.stringify('Ascensio System SIA'), - __APP_TITLE_TEXT__: JSON.stringify(process.env.APP_TITLE_TEXT ? process.env.APP_TITLE_TEXT : 'ONLYOFFICE') + __APP_TITLE_TEXT__: JSON.stringify(process.env.APP_TITLE_TEXT ? process.env.APP_TITLE_TEXT : 'ONLYOFFICE'), + __COMPANY_NAME__: JSON.stringify(process.env.COMPANY_NAME ? process.env.COMPANY_NAME : 'ONLYOFFICE') }), ...(env === 'production' ? [ From cf7141f7560f44a96b3d790a57fc4651441b7a1f Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Mon, 12 Apr 2021 15:42:20 +0300 Subject: [PATCH 16/43] [DE mobile] Added macros mode initialization when loading a document --- apps/documenteditor/mobile/src/controller/Main.jsx | 12 +++++++++++- .../src/controller/settings/ApplicationSettings.jsx | 3 +-- .../mobile/src/view/settings/ApplicationSettings.jsx | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/apps/documenteditor/mobile/src/controller/Main.jsx b/apps/documenteditor/mobile/src/controller/Main.jsx index bdfc7fcff..4cb66c3ee 100644 --- a/apps/documenteditor/mobile/src/controller/Main.jsx +++ b/apps/documenteditor/mobile/src/controller/Main.jsx @@ -26,7 +26,8 @@ import LongActionsController from "./LongActions"; "storeParagraphSettings", "storeTableSettings", "storeDocumentInfo", - "storeChartSettings" + "storeChartSettings", + "storeApplicationSettings" ) class MainController extends Component { constructor(props) { @@ -83,6 +84,15 @@ class MainController extends Component { this.editorConfig.lang && this.api.asc_setLocale(this.editorConfig.lang); + let value = LocalStorage.getItem("de-mobile-macros-mode"); + if (value === null) { + value = this.editorConfig.customization ? this.editorConfig.customization.macrosMode : 'warn'; + value = (value === 'enable') ? 1 : (value === 'disable' ? 2 : 0); + } else { + value = parseInt(value); + } + this.props.storeApplicationSettings.changeMacrosSettings(value); + Common.Notifications.trigger('configOptionsFill'); }; diff --git a/apps/documenteditor/mobile/src/controller/settings/ApplicationSettings.jsx b/apps/documenteditor/mobile/src/controller/settings/ApplicationSettings.jsx index 4f8275494..c1239d2ab 100644 --- a/apps/documenteditor/mobile/src/controller/settings/ApplicationSettings.jsx +++ b/apps/documenteditor/mobile/src/controller/settings/ApplicationSettings.jsx @@ -57,8 +57,7 @@ class ApplicationSettingsController extends Component { } setMacrosSettings(value) { - // Common.Utils.InternalSettings.set("de-mobile-macros-mode", +value); - // Common.localStorage.setItem("de-mobile-macros-mode", +value); + LocalStorage.setItem("de-mobile-macros-mode", value); } render() { diff --git a/apps/documenteditor/mobile/src/view/settings/ApplicationSettings.jsx b/apps/documenteditor/mobile/src/view/settings/ApplicationSettings.jsx index 956195034..848438779 100644 --- a/apps/documenteditor/mobile/src/view/settings/ApplicationSettings.jsx +++ b/apps/documenteditor/mobile/src/view/settings/ApplicationSettings.jsx @@ -106,7 +106,7 @@ const PageMacrosSettings = props => { const changeMacros = value => { store.changeMacrosSettings(value); - // props.setMacrosSettings(value); + props.setMacrosSettings(value); }; return ( From 2bd901f3a66f6c8a8ec2408215651dd17efe0fe7 Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Mon, 12 Apr 2021 18:09:08 +0300 Subject: [PATCH 17/43] [DE mobile] changes for private branch --- apps/documenteditor/mobile/src/store/paragraphSettings.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/apps/documenteditor/mobile/src/store/paragraphSettings.js b/apps/documenteditor/mobile/src/store/paragraphSettings.js index ed5bd2004..ecbe07431 100644 --- a/apps/documenteditor/mobile/src/store/paragraphSettings.js +++ b/apps/documenteditor/mobile/src/store/paragraphSettings.js @@ -20,11 +20,6 @@ export class storeParagraphSettings { styleName = undefined; initEditorStyles (styles) { - this.styles = styles.get_MergedStyles(); - this.styleThumbSize = { - width : styles.STYLE_THUMBNAIL_WIDTH, - height : styles.STYLE_THUMBNAIL_HEIGHT - }; } get paragraphStyles () { @@ -39,7 +34,6 @@ export class storeParagraphSettings { } changeParaStyleName (name) { - this.styleName = name; } backColor = undefined; From a9dda7fe6f6735548025b901ec6e1b6d07d0dbe9 Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Mon, 12 Apr 2021 18:10:03 +0300 Subject: [PATCH 18/43] [common] don't open context menu if no items --- .../common/mobile/lib/controller/ContextMenu.jsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/apps/common/mobile/lib/controller/ContextMenu.jsx b/apps/common/mobile/lib/controller/ContextMenu.jsx index ff56b40d8..61ddbd04f 100644 --- a/apps/common/mobile/lib/controller/ContextMenu.jsx +++ b/apps/common/mobile/lib/controller/ContextMenu.jsx @@ -109,15 +109,17 @@ class ContextMenuController extends Component { extraItems: this.initExtraItems() }); - this.$targetEl.css({left: `${x}px`, top: `${y}px`}); - const popover = f7.popover.open(idContextMenuElement, idCntextMenuTargetElement); + if ( this.state.items.length > 0 ) { + this.$targetEl.css({left: `${x}px`, top: `${y}px`}); + const popover = f7.popover.open(idContextMenuElement, idCntextMenuTargetElement); - if ( Device.android ) - this.offsetPopoverTop(popover); + if (Device.android) + this.offsetPopoverTop(popover); - this.setState(state => { - return {opened: true} - }); + this.setState(state => { + return {opened: true} + }); + } } } From 84650bb71d3aca6ca9fc7182b2bd2485a0723f1c Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Mon, 12 Apr 2021 18:10:53 +0300 Subject: [PATCH 19/43] [DE mobile] refactoring --- .../mobile/src/controller/ContextMenu.jsx | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/apps/documenteditor/mobile/src/controller/ContextMenu.jsx b/apps/documenteditor/mobile/src/controller/ContextMenu.jsx index 14facac9e..a832cbf31 100644 --- a/apps/documenteditor/mobile/src/controller/ContextMenu.jsx +++ b/apps/documenteditor/mobile/src/controller/ContextMenu.jsx @@ -164,14 +164,13 @@ class ContextMenu extends ContextMenuController { const dialog = f7.dialog.create({ title: _t.menuSplit, text: '', - content: - '
' + - '
' + - '
' + _t.textColumns + '
' + - '
' + _t.textRows + '
' + - '
' + - '
' + - '
', + content: `
+
+
${_t.textColumns}
+
${_t.textRows}
+
+
+
`, buttons: [ { text: _t.menuCancel From b0c9a1c5d28371d78ae54854f74f9bdaa8ee9efa Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Mon, 12 Apr 2021 18:16:34 +0300 Subject: [PATCH 20/43] [DE mobile] changes for private Editor controller --- .../mobile/src/controller/ContextMenu.jsx | 234 +----------------- apps/documenteditor/mobile/src/lib/patch.jsx | 5 +- .../mobile/src/store/focusObjects.js | 99 +------- 3 files changed, 24 insertions(+), 314 deletions(-) diff --git a/apps/documenteditor/mobile/src/controller/ContextMenu.jsx b/apps/documenteditor/mobile/src/controller/ContextMenu.jsx index a832cbf31..aedb54c99 100644 --- a/apps/documenteditor/mobile/src/controller/ContextMenu.jsx +++ b/apps/documenteditor/mobile/src/controller/ContextMenu.jsx @@ -7,6 +7,7 @@ import { LocalStorage } from '../../../../common/mobile/utils/LocalStorage'; 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 => ({ isEdit: stores.storeAppOptions.isEdit, @@ -64,28 +65,25 @@ class ContextMenu extends ContextMenuController { onMenuItemClick(action) { super.onMenuItemClick(action); + if ( EditorUIController.ContextMenu.handleMenuItemClick(this, action) ) + return; + const api = Common.EditorApi.get(); switch (action) { case 'cut': - if (!api.Cut() && !LocalStorage.getBool("de-hide-copy-cut-paste-warning")) { + if ( !LocalStorage.getBool("de-hide-copy-cut-paste-warning") ) this.showCopyCutPasteModal(); - } + break; case 'copy': - if (!api.Copy() && !LocalStorage.getBool("de-hide-copy-cut-paste-warning")) { + if ( !LocalStorage.getBool("de-hide-copy-cut-paste-warning") ) this.showCopyCutPasteModal(); - } + break; case 'paste': - if (!api.Paste() && !LocalStorage.getBool("de-hide-copy-cut-paste-warning")) { + if ( !LocalStorage.getBool("de-hide-copy-cut-paste-warning") ) this.showCopyCutPasteModal(); - } - break; - case 'addcomment': - Common.Notifications.trigger('addcomment'); - break; - case 'viewcomment': - Common.Notifications.trigger('viewcomment'); + break; case 'review': setTimeout(() => { @@ -97,18 +95,9 @@ class ContextMenu extends ContextMenuController { this.props.openOptions('coauth', 'cm-review-change'); }, 400); break; - case 'merge': - api.MergeCells(); - break; case 'split': this.showSplitModal(); break; - case 'delete': - api.asc_Remove(); - break; - case 'deletetable': - api.remTable(); - break; case 'edit': setTimeout(() => { this.props.openOptions('edit'); @@ -117,17 +106,7 @@ class ContextMenu extends ContextMenuController { case 'addlink': setTimeout(() => { this.props.openOptions('add', 'link'); - }, 400) - break; - 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); + }, 400); break; } @@ -228,196 +207,7 @@ class ContextMenu extends ContextMenuController { initMenuItems() { if ( !Common.EditorApi ) return []; - const { t } = this.props; - const _t = t("ContextMenu", { returnObjects: true }); - - const { isEdit, canViewComments, canReview, isDisconnected } = this.props; - - const api = Common.EditorApi.get(); - const stack = api.getSelectedElements(); - const canCopy = api.can_CopyCut(); - - let itemsIcon = [], - itemsText = []; - - if ( canCopy ) { - itemsIcon.push({ - event: 'copy', - icon: 'icon-copy' - }); - } - - if ( canViewComments && this.isComments && !isEdit ) { - itemsText.push({ - caption: _t.menuViewComment, - event: 'viewcomment' - }); - } - - let isText = false, - isTable = false, - isImage = false, - isChart = false, - isShape = false, - isLink = false, - lockedText = false, - lockedTable = false, - lockedImage = false, - lockedHeader = false; - - stack.forEach(item => { - const objectType = item.get_ObjectType(), - objectValue = item.get_ObjectValue(); - - if ( objectType == Asc.c_oAscTypeSelectElement.Header ) { - lockedHeader = objectValue.get_Locked(); - } else - if ( objectType == Asc.c_oAscTypeSelectElement.Paragraph ) { - lockedText = objectValue.get_Locked(); - isText = true; - } else - if ( objectType == Asc.c_oAscTypeSelectElement.Image ) { - lockedImage = objectValue.get_Locked(); - if ( objectValue && objectValue.get_ChartProperties() ) { - isChart = true; - } else - if ( objectValue && objectValue.get_ShapeProperties() ) { - isShape = true; - } else { - isImage = true; - } - } else - if ( objectType == Asc.c_oAscTypeSelectElement.Table ) { - lockedTable = objectValue.get_Locked(); - isTable = true; - } else - if ( objectType == Asc.c_oAscTypeSelectElement.Hyperlink ) { - isLink = true; - } - }); - - if ( stack.length > 0 ) { - const swapItems = function(items, indexBefore, indexAfter) { - items[indexAfter] = items.splice(indexBefore, 1, items[indexAfter])[0]; - }; - - if ( isEdit && !isDisconnected ) { - if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader && canCopy ) { - itemsIcon.push({ - event: 'cut', - icon: 'icon-cut' - }); - - // Swap 'Copy' and 'Cut' - swapItems(itemsIcon, 0, 1); - } - - if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader ) { - itemsIcon.push({ - event: 'paste', - icon: 'icon-paste' - }); - } - - if ( isTable && api.CheckBeforeMergeCells() && !lockedTable && !lockedHeader) { - itemsText.push({ - caption: _t.menuMerge, - event: 'merge' - }); - } - - if ( isTable && api.CheckBeforeSplitCells() && !lockedTable && !lockedHeader ) { - itemsText.push({ - caption: _t.menuSplit, - event: 'split' - }); - } - - if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader ) { - itemsText.push({ - caption: _t.menuDelete, - event: 'delete' - }); - } - - if ( isTable && !lockedTable && !lockedText && !lockedHeader ) { - itemsText.push({ - caption: _t.menuDeleteTable, - event: 'deletetable' - }); - } - - if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader ){ - itemsText.push({ - caption: _t.menuEdit, - event: 'edit' - }); - } - - if ( !!api.can_AddHyperlink() && !lockedHeader) { - itemsText.push({ - caption: _t.menuAddLink, - event: 'addlink' - }); - } - - if ( canReview ) { - if (this.inRevisionChange) { - itemsText.push({ - caption: _t.menuReviewChange, - event: 'reviewchange' - }); - } else { - itemsText.push({ - caption: _t.menuReview, - event: 'review' - }); - } - } - - if ( this.isComments && canViewComments ) { - itemsText.push({ - caption: _t.menuViewComment, - event: 'viewcomment' - }); - } - - const isObject = isShape || isChart || isImage || isTable; - const hideAddComment = !canViewComments || api.can_AddQuotedComment() === false || lockedText || lockedTable || lockedImage || lockedHeader || (!isText && isObject); - if ( !hideAddComment ) { - itemsText.push({ - caption: _t.menuAddComment, - event: 'addcomment' - }); - } - } - } - - if ( isLink ) { - itemsText.push({ - caption: _t.menuOpenLink, - event: 'openlink' - }); - } - - if ( Device.phone && itemsText.length > 2 ) { - this.extraItems = itemsText.splice(2,itemsText.length, { - caption: _t.menuMore, - event: 'showActionSheet' - }); - } - - return itemsIcon.concat(itemsText); - // return [{ - // caption: 'Edit', - // event: 'edit' - // }, { - // caption: 'View', - // event: 'view' - // }, { - // icon: 'icon-paste', - // event: 'review' - // }]; + return EditorUIController.ContextMenu.mapMenuItems(this); } initExtraItems () { diff --git a/apps/documenteditor/mobile/src/lib/patch.jsx b/apps/documenteditor/mobile/src/lib/patch.jsx index d3d114743..963aca451 100644 --- a/apps/documenteditor/mobile/src/lib/patch.jsx +++ b/apps/documenteditor/mobile/src/lib/patch.jsx @@ -14,7 +14,10 @@ EditorUIController.getToolbarOptions = () => { EditorUIController.initFonts = () => null; EditorUIController.initEditorStyles = () => null; EditorUIController.initFocusObjects = () => null; -EditorUIController.filterFocusObjects = () => []; EditorUIController.initTableTemplates = () => null; +EditorUIController.ContextMenu = { + mapMenuItems: () => [], + handleMenuItemClick: () => true, +}; export default EditorUIController; diff --git a/apps/documenteditor/mobile/src/store/focusObjects.js b/apps/documenteditor/mobile/src/store/focusObjects.js index 7b75f2cec..566463bee 100644 --- a/apps/documenteditor/mobile/src/store/focusObjects.js +++ b/apps/documenteditor/mobile/src/store/focusObjects.js @@ -24,11 +24,10 @@ export class storeFocusObjects { _headerType = 1; resetFocusObjects (objects) { - this._focusObjects = objects; } get settings() { - return EditorUIController.filterFocusObjects(this._focusObjects); + return !!this.intf ? this.intf.filterFocusObjects() : null; } get headerType() { @@ -42,83 +41,23 @@ export class storeFocusObjects { } get headerObject() { - const headers = []; - for (let object of this._focusObjects) { - if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Header) { - headers.push(object); - } - } - if (headers.length > 0) { - const object = headers[headers.length - 1]; // get top - return object.get_ObjectValue(); - } else { - return undefined; - } + return !!this.intf ? this.intf.getHeaderObject() : null; } get paragraphObject() { - const paragraphs = []; - for (let object of this._focusObjects) { - if (object.get_ObjectType() === Asc.c_oAscTypeSelectElement.Paragraph) { - paragraphs.push(object); - } - } - if (paragraphs.length > 0) { - const object = paragraphs[paragraphs.length - 1]; // get top - return object.get_ObjectValue(); - } else { - return undefined; - } + return !!this.intf ? this.intf.getParagraphObject() : null; } get shapeObject() { - const shapes = []; - for (let object of this._focusObjects) { - if (object.get_ObjectType() === Asc.c_oAscTypeSelectElement.Image) { - if (object.get_ObjectValue() && object.get_ObjectValue().get_ShapeProperties()) { - shapes.push(object); - } - } - } - if (shapes.length > 0) { - const object = shapes[shapes.length - 1]; // get top - return object.get_ObjectValue(); - } else { - return undefined; - } + return !!this.intf ? this.intf.getShapeObject() : null; } get imageObject() { - const images = []; - for (let object of this._focusObjects) { - if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Image) { - const imageObject = object.get_ObjectValue(); - if (imageObject && imageObject.get_ShapeProperties() === null && imageObject.get_ChartProperties() === null) { - images.push(object); - } - } - } - if (images.length > 0) { - const object = images[images.length - 1]; // get top - return object.get_ObjectValue(); - } else { - return undefined; - } + return !!this.intf ? this.intf.getImageObject() : null; } get tableObject() { - const tables = []; - for (let object of this._focusObjects) { - if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Table) { - tables.push(object); - } - } - if (tables.length > 0) { - const object = tables[tables.length - 1]; // get top table - return object.get_ObjectValue(); - } else { - return undefined; - } + return !!this.intf ? this.intf.getTableObject() : null; } get isTableInStack() { @@ -131,32 +70,10 @@ export class storeFocusObjects { } get chartObject() { - const charts = []; - for (let object of this._focusObjects) { - if (object.get_ObjectValue() && object.get_ObjectValue().get_ChartProperties()) { - charts.push(object); - } - } - if (charts.length > 0) { - const object = charts[charts.length - 1]; // get top table - return object.get_ObjectValue(); - } else { - return undefined; - } + return !!this.intf ? this.intf.getChartObject() : null; } get linkObject() { - const links = []; - for (let object of this._focusObjects) { - if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Hyperlink) { - links.push(object); - } - } - if (links.length > 0) { - const object = links[links.length - 1]; // get top - return object.get_ObjectValue(); - } else { - return undefined; - } + return !!this.intf ? this.intf.getLinkObject() : null; } } \ No newline at end of file From 89d8b3703ef59d1406c1c3ef73e54cc38407fd0e Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Mon, 12 Apr 2021 19:03:42 +0300 Subject: [PATCH 21/43] [DE mobile] Make main controller, add run autostart macroses --- apps/documenteditor/mobile/locale/en.json | 6 +- .../mobile/src/controller/Error.jsx | 1 + .../mobile/src/controller/Main.jsx | 77 ++++++++++++++++--- 3 files changed, 74 insertions(+), 10 deletions(-) diff --git a/apps/documenteditor/mobile/locale/en.json b/apps/documenteditor/mobile/locale/en.json index e508cb033..9ca0208b9 100644 --- a/apps/documenteditor/mobile/locale/en.json +++ b/apps/documenteditor/mobile/locale/en.json @@ -52,7 +52,11 @@ "errorAccessDeny": "You are trying to perform an action you do not have rights for.
Please contact your Document Server administrator.", "errorUpdateVersion": "The file version has been changed. The page will be reloaded.", - "titleUpdateVersion": "Version changed" + "titleUpdateVersion": "Version changed", + "textHasMacros": "The file contains automatic macros.
Do you want to run macros?", + "textRemember": "Remember my choice", + "textYes": "Yes", + "textNo": "No" }, "Error": { "criticalErrorTitle": "Error", diff --git a/apps/documenteditor/mobile/src/controller/Error.jsx b/apps/documenteditor/mobile/src/controller/Error.jsx index f1fd7074b..6ae81ef0d 100644 --- a/apps/documenteditor/mobile/src/controller/Error.jsx +++ b/apps/documenteditor/mobile/src/controller/Error.jsx @@ -209,6 +209,7 @@ const ErrorController = inject('storeAppOptions')(({storeAppOptions, LoadingDocu } f7.dialog.create({ + cssClass: 'error-dialog', title : config.title, text : config.msg, buttons: [ diff --git a/apps/documenteditor/mobile/src/controller/Main.jsx b/apps/documenteditor/mobile/src/controller/Main.jsx index 4cb66c3ee..391f6dbdb 100644 --- a/apps/documenteditor/mobile/src/controller/Main.jsx +++ b/apps/documenteditor/mobile/src/controller/Main.jsx @@ -124,21 +124,21 @@ class MainController extends Component { docInfo.put_Permissions(_permissions); docInfo.put_EncryptedInfo(this.editorConfig.encryptionKeys); - // var enable = !this.editorConfig.customization || (this.editorConfig.customization.macros!==false); - // docInfo.asc_putIsEnabledMacroses(!!enable); - // enable = !this.editorConfig.customization || (this.editorConfig.customization.plugins!==false); - // docInfo.asc_putIsEnabledPlugins(!!enable); + let enable = !this.editorConfig.customization || (this.editorConfig.customization.macros !== false); + docInfo.asc_putIsEnabledMacroses(!!enable); + enable = !this.editorConfig.customization || (this.editorConfig.customization.plugins !== false); + docInfo.asc_putIsEnabledPlugins(!!enable); - // let type = /^(?:(pdf|djvu|xps))$/.exec(data.doc.fileType); - // if (type && typeof type[1] === 'string') { - // this.permissions.edit = this.permissions.review = false; - // } + const type = /^(?:(pdf|djvu|xps))$/.exec(data.doc.fileType); + if (type && typeof type[1] === 'string') { + this.permissions.edit = this.permissions.review = false; + } } this.api.asc_registerCallback('asc_onGetEditorPermissions', onEditorPermissions); this.api.asc_registerCallback('asc_onDocumentContentReady', onDocumentContentReady); this.api.asc_registerCallback('asc_onLicenseChanged', this.onLicenseChanged.bind(this)); - // this.api.asc_registerCallback('asc_onRunAutostartMacroses', _.bind(this.onRunAutostartMacroses, this)); + this.api.asc_registerCallback('asc_onRunAutostartMacroses', this.onRunAutostartMacroses.bind(this)); this.api.asc_setDocInfo(docInfo); this.api.asc_getEditorPermissions(this.editorConfig.licenseUrl, this.editorConfig.customerId); @@ -258,6 +258,19 @@ class MainController extends Component { 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); }); @@ -677,6 +690,52 @@ class MainController extends Component { } } + onRunAutostartMacroses () { + const config = this.props.storeAppOptions.config; + const enable = !config.customization || (config.customization.macros !== false); + if (enable) { + const value = this.props.storeApplicationSettings.macrosMode; + if (value === 1) { + this.api.asc_runAutostartMacroses(); + } else if (value === 0) { + const _t = this._t; + f7.dialog.create({ + title: _t.notcriticalErrorTitle, + text: _t.textHasMacros, + content: `
+ + ${_t.textRemember} +
`, + buttons: [{ + text: _t.textYes, + onClick: () => { + const dontshow = $$('input[name="checkbox-show-macros"]').prop('checked'); + if (dontshow) { + this.props.storeApplicationSettings.changeMacrosSettings(1); + LocalStorage.setItem("de-mobile-macros-mode", 1); + } + setTimeout(() => { + this.api.asc_runAutostartMacroses(); + }, 1); + }}, + { + text: _t.textNo, + onClick: () => { + const dontshow = $$('input[name="checkbox-show-macros"]').prop('checked'); + if (dontshow) { + this.props.storeApplicationSettings.changeMacrosSettings(2); + LocalStorage.setItem("de-mobile-macros-mode", 2); + } + } + }] + }).open(); + } + } + } + render() { return ( From 30b08d1dbb6df238da7b87d170049f325d95c6e7 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Tue, 13 Apr 2021 13:51:21 +0300 Subject: [PATCH 22/43] [DE mobile] Make document content ready in main controller, fix analytics error --- apps/common/Analytics.js | 4 +- .../mobile/src/controller/Main.jsx | 49 ++++++++++++++++--- .../settings/ApplicationSettings.jsx | 11 ++--- 3 files changed, 47 insertions(+), 17 deletions(-) diff --git a/apps/common/Analytics.js b/apps/common/Analytics.js index f2985be6c..8c7bc4cd8 100644 --- a/apps/common/Analytics.js +++ b/apps/common/Analytics.js @@ -30,8 +30,8 @@ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ -if (Common === undefined) - var Common = {}; +if (window.Common === undefined) + window.Common = {}; Common.component = Common.component || {}; diff --git a/apps/documenteditor/mobile/src/controller/Main.jsx b/apps/documenteditor/mobile/src/controller/Main.jsx index 391f6dbdb..1b92e6b97 100644 --- a/apps/documenteditor/mobile/src/controller/Main.jsx +++ b/apps/documenteditor/mobile/src/controller/Main.jsx @@ -191,26 +191,59 @@ class MainController extends Component { }; const onDocumentContentReady = () => { - if (this.props.storeAppOptions.isEdit && this.needToUpdateVersion) { - Common.Notifications.trigger('api:disconnect'); - } + const appOptions = this.props.storeAppOptions; + const appSettings = this.props.storeApplicationSettings; - this.applyLicense(); - - Common.Gateway.documentReady(); f7.emit('resize'); - Common.Notifications.trigger('document:ready'); - this._isDocReady = true; + this.api.SetDrawingFreeze(false); + Common.Notifications.trigger('preloader:close'); Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], this.LoadingDocument); + let value = LocalStorage.getItem("de-settings-zoom"); + const zf = (value !== null) ? parseInt(value) : (appOptions.customization && appOptions.customization.zoom ? parseInt(appOptions.customization.zoom) : 100); + (zf === -1) ? this.api.zoomFitToPage() : ((zf === -2) ? this.api.zoomFitToWidth() : this.api.zoom(zf>0 ? zf : 100)); + + value = LocalStorage.getBool("de-mobile-spellcheck", !(appOptions.customization && appOptions.customization.spellcheck === false)); + appSettings.changeSpellCheck(value); + this.api.asc_setSpellCheck(value); + + this.updateWindowTitle(true); + + this.api.SetTextBoxInputMode(LocalStorage.getBool("de-settings-inputmode")); + + value = LocalStorage.getBool("de-mobile-no-characters"); + appSettings.changeNoCharacters(value); + this.api.put_ShowParaMarks(value); + + value = LocalStorage.getBool("de-mobile-hidden-borders"); + appSettings.changeShowTableEmptyLine(value); + this.api.put_ShowTableEmptyLine(value); + + if (appOptions.isEdit && this.needToUpdateVersion) { + Common.Notifications.trigger('api:disconnect'); + } + Common.Gateway.on('processsaveresult', this.onProcessSaveResult.bind(this)); 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.zoomFitToWidth(); + this.api.asc_GetDefaultTableStyles && setTimeout(() => {this.api.asc_GetDefaultTableStyles()}, 1); + + this.applyLicense(); + + Common.Notifications.trigger('document:ready'); + Common.Gateway.documentReady(); }; const _process_array = (array, fn) => { diff --git a/apps/documenteditor/mobile/src/controller/settings/ApplicationSettings.jsx b/apps/documenteditor/mobile/src/controller/settings/ApplicationSettings.jsx index c1239d2ab..388ea1ab7 100644 --- a/apps/documenteditor/mobile/src/controller/settings/ApplicationSettings.jsx +++ b/apps/documenteditor/mobile/src/controller/settings/ApplicationSettings.jsx @@ -18,20 +18,17 @@ class ApplicationSettingsController extends Component { } switchSpellCheck(value) { - const api = Common.EditorApi.get(); - // let state = value === '1' ? true : false; - // Common.localStorage.setItem("de-mobile-spellcheck", value ? 1 : 0); - api.asc_setSpellCheck(value); + LocalStorage.setBool("de-mobile-spellcheck", value); + Common.EditorApi.get().asc_setSpellCheck(value); } switchNoCharacters(value) { - LocalStorage.setItem("de-mobile-no-characters", value); - + LocalStorage.setBool("de-mobile-no-characters", value); Common.EditorApi.get().put_ShowParaMarks(value); } switchShowTableEmptyLine(value) { - LocalStorage.setItem("de-mobile-hidden-borders", value); + LocalStorage.setBool("de-mobile-hidden-borders", value); Common.EditorApi.get().put_ShowTableEmptyLine(value); } From cd1aa44b5c81b73258c6b762fa7d62749d2f7afc Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Tue, 13 Apr 2021 15:37:31 +0300 Subject: [PATCH 23/43] [DE mobile] Hide options in toolbar for view mode --- .../mobile/src/controller/Toolbar.jsx | 1 + apps/documenteditor/mobile/src/view/Toolbar.jsx | 16 +++++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/apps/documenteditor/mobile/src/controller/Toolbar.jsx b/apps/documenteditor/mobile/src/controller/Toolbar.jsx index 609c072fe..b6f32e31f 100644 --- a/apps/documenteditor/mobile/src/controller/Toolbar.jsx +++ b/apps/documenteditor/mobile/src/controller/Toolbar.jsx @@ -174,6 +174,7 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeReview')(prop return ( { {props.isShowBack && } - - + {props.isEdit && EditorUIController.getUndoRedo({ + disabledUndo: !props.isCanUndo, + disabledRedo: !props.isCanRedo, + onUndoClick: props.onUndo, + onRedoClick: props.onRedo + })} {!Device.phone && {props.docTitle}} - { - EditorUIController.getToolbarOptions({ + {props.isEdit && EditorUIController.getToolbarOptions({ disabled: disableEditBtn || props.disabledControls, onEditClick: e => props.openOptions('edit'), - onAddClick: e => props.openOptions('add'), - }) - } + onAddClick: e => props.openOptions('add') + })} { Device.phone ? null : } {props.displayCollaboration && props.openOptions('coauth')}>} props.openOptions('settings')}> From 437fed37c064648e639cffd941ab9c2372f2871d Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Tue, 13 Apr 2021 17:41:24 +0300 Subject: [PATCH 24/43] [DE mobile] Add reader mode and print handlers in settings --- .../mobile/src/controller/Toolbar.jsx | 2 + .../src/controller/settings/Settings.jsx | 58 +++++++++++++++++++ apps/documenteditor/mobile/src/page/main.jsx | 2 +- .../mobile/src/store/appOptions.js | 10 +++- .../mobile/src/view/Toolbar.jsx | 2 +- .../mobile/src/view/settings/Settings.jsx | 46 ++++----------- 6 files changed, 82 insertions(+), 38 deletions(-) create mode 100644 apps/documenteditor/mobile/src/controller/settings/Settings.jsx diff --git a/apps/documenteditor/mobile/src/controller/Toolbar.jsx b/apps/documenteditor/mobile/src/controller/Toolbar.jsx index b6f32e31f..9ff6ce8e8 100644 --- a/apps/documenteditor/mobile/src/controller/Toolbar.jsx +++ b/apps/documenteditor/mobile/src/controller/Toolbar.jsx @@ -13,6 +13,7 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeReview')(prop const displayMode = props.storeReview.displayMode; const stateDisplayMode = displayMode == "final" || displayMode == "original" ? true : false; const displayCollaboration = props.users.hasEditUsers || appOptions.canViewComments || appOptions.canReview || appOptions.canViewReview; + const readerMode = appOptions.readerMode; useEffect(() => { const onDocumentReady = () => { @@ -188,6 +189,7 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeReview')(prop disabledEditControls={disabledEditControls} disabledSettings={disabledSettings} displayCollaboration={displayCollaboration} + readerMode={readerMode} /> ) }); diff --git a/apps/documenteditor/mobile/src/controller/settings/Settings.jsx b/apps/documenteditor/mobile/src/controller/settings/Settings.jsx new file mode 100644 index 000000000..4eab56d95 --- /dev/null +++ b/apps/documenteditor/mobile/src/controller/settings/Settings.jsx @@ -0,0 +1,58 @@ +import React, {useEffect} from 'react'; +import { useTranslation } from 'react-i18next'; +import {f7} from 'framework7-react'; +import { observer, inject } from "mobx-react"; +import {Device} from '../../../../../common/mobile/utils/device'; + +import SettingsView from "../../view/settings/Settings"; + +const Settings = props => { + useEffect(() => { + if ( Device.phone ) { + f7.popup.open('.settings-popup'); + } else { + f7.popover.open('#settings-popover', '#btn-settings'); + } + + return () => { + // component will unmount + } + }); + + const onviewclosed = () => { + if ( props.onclosed ) + props.onclosed(); + }; + + const closeModal = () => { + if (Device.phone) { + f7.sheet.close('.settings-popup'); + } else { + f7.popover.close('#settings-popover'); + } + }; + + const onReaderMode = () => { + const appOptions = props.storeAppOptions; + appOptions.changeReaderMode(); + + Common.EditorApi.get().ChangeReaderMode(); + + if (Device.phone) { + setTimeout(() => { + closeModal(); + }, 1); + } + } + + const onPrint = () => { + setTimeout(() => { + Common.EditorApi.get().asc_Print(); + }, 1); + closeModal(); + } + + return +}; + +export default inject("storeAppOptions")(observer(Settings)); \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/page/main.jsx b/apps/documenteditor/mobile/src/page/main.jsx index 43a94710f..6c4586868 100644 --- a/apps/documenteditor/mobile/src/page/main.jsx +++ b/apps/documenteditor/mobile/src/page/main.jsx @@ -6,7 +6,7 @@ import { inject } from "mobx-react"; import EditOptions from '../view/edit/Edit'; import AddOptions from '../view/add/Add'; -import Settings from '../view/settings/Settings'; +import Settings from '../controller/settings/Settings'; import Collaboration from '../../../../common/mobile/lib/view/collaboration/Collaboration.jsx' import { Device } from '../../../../common/mobile/utils/device' import { Search, SearchSettings } from '../controller/Search'; diff --git a/apps/documenteditor/mobile/src/store/appOptions.js b/apps/documenteditor/mobile/src/store/appOptions.js index 13f521bba..f3bb99b12 100644 --- a/apps/documenteditor/mobile/src/store/appOptions.js +++ b/apps/documenteditor/mobile/src/store/appOptions.js @@ -11,7 +11,10 @@ export class storeAppOptions { setCanViewReview: action, lostEditingRights: observable, - changeEditingRights: action + changeEditingRights: action, + + readerMode: observable, + changeReaderMode: action }); } @@ -24,6 +27,11 @@ export class storeAppOptions { this.lostEditingRights = value; } + readerMode = false; + changeReaderMode () { + this.readerMode = !this.readerMode; + } + config = {}; setConfigOptions (config) { this.config = config; diff --git a/apps/documenteditor/mobile/src/view/Toolbar.jsx b/apps/documenteditor/mobile/src/view/Toolbar.jsx index 76804db1a..d73db145c 100644 --- a/apps/documenteditor/mobile/src/view/Toolbar.jsx +++ b/apps/documenteditor/mobile/src/view/Toolbar.jsx @@ -23,7 +23,7 @@ const ToolbarView = props => { onEditClick: e => props.openOptions('edit'), onAddClick: e => props.openOptions('add') })} - { Device.phone ? null : } + { Device.phone ? null : } {props.displayCollaboration && props.openOptions('coauth')}>} props.openOptions('settings')}> diff --git a/apps/documenteditor/mobile/src/view/settings/Settings.jsx b/apps/documenteditor/mobile/src/view/settings/Settings.jsx index afe8b68e0..920df80ca 100644 --- a/apps/documenteditor/mobile/src/view/settings/Settings.jsx +++ b/apps/documenteditor/mobile/src/view/settings/Settings.jsx @@ -1,6 +1,6 @@ import React, {Component, useEffect} from 'react'; -import {View,Page,Navbar,NavRight,Link,Popup,Popover,Icon,ListItem,List} from 'framework7-react'; -import { withTranslation } from 'react-i18next'; +import {View, Page, Navbar, NavRight, Link, Popup, Popover, Icon,ListItem, List, Toggle} from 'framework7-react'; +import { useTranslation } from 'react-i18next'; import {f7} from 'framework7-react'; import { observer, inject } from "mobx-react"; import {Device} from '../../../../../common/mobile/utils/device'; @@ -57,8 +57,8 @@ const routes = [ ]; -const SettingsList = inject("storeAppOptions")( observer( withTranslation()( props => { - const {t} = props; +const SettingsList = inject("storeAppOptions")(observer(props => { + const { t } = useTranslation(); const _t = t('Settings', {returnObjects: true}); const navbar = {!props.inPopover && {_t.textDone}} @@ -113,14 +113,14 @@ const SettingsList = inject("storeAppOptions")( observer( withTranslation()( pro {navbar} {!props.inPopover && - + } {_canReader && {/*ToDo*/} - {}}/> + {props.onReaderMode()}}/> } {/*ToDo: settings-orthography*/} @@ -143,7 +143,7 @@ const SettingsList = inject("storeAppOptions")( observer( withTranslation()( pro } {_canPrint && - + } @@ -164,7 +164,7 @@ const SettingsList = inject("storeAppOptions")( observer( withTranslation()( pro ) -}))); +})); class SettingsView extends Component { constructor(props) { @@ -182,37 +182,13 @@ class SettingsView extends Component { return ( show_popover ? this.props.onclosed()}> - + : this.props.onclosed()}> - + ) } } -const Settings = props => { - useEffect(() => { - if ( Device.phone ) - f7.popup.open('.settings-popup'); - else f7.popover.open('#settings-popover', '#btn-settings'); - - return () => { - // component will unmount - } - }); - - - const onviewclosed = () => { - if ( props.onclosed ) - props.onclosed(); - }; - - // if ( Device.phone ) { - // return - // } - - return -}; - -export default Settings; +export default SettingsView; From e55c823cad21efe73ed94b800959e52066a7c841 Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Tue, 13 Apr 2021 17:54:09 +0300 Subject: [PATCH 25/43] [PE] added controller for private code --- apps/presentationeditor/mobile/src/controller/Main.jsx | 3 +++ apps/presentationeditor/mobile/src/lib/patch.jsx | 6 ++++++ 2 files changed, 9 insertions(+) create mode 100644 apps/presentationeditor/mobile/src/lib/patch.jsx diff --git a/apps/presentationeditor/mobile/src/controller/Main.jsx b/apps/presentationeditor/mobile/src/controller/Main.jsx index 0156bf227..1c7a9bd9b 100644 --- a/apps/presentationeditor/mobile/src/controller/Main.jsx +++ b/apps/presentationeditor/mobile/src/controller/Main.jsx @@ -4,6 +4,7 @@ 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 { CommentsController, AddCommentController, @@ -44,6 +45,8 @@ class MainController extends Component { }; const loadConfig = data => { + EditorUIController.isSupportEditFeature(); + console.log('load config'); this.editorConfig = Object.assign({}, this.editorConfig, data.config); diff --git a/apps/presentationeditor/mobile/src/lib/patch.jsx b/apps/presentationeditor/mobile/src/lib/patch.jsx new file mode 100644 index 000000000..ec7b37a2c --- /dev/null +++ b/apps/presentationeditor/mobile/src/lib/patch.jsx @@ -0,0 +1,6 @@ + +const EditorUIController = () => null; + +EditorUIController.isSupportEditFeature = () => false; + +export default EditorUIController; From 8943602605f407c4f38354dee5c92682610b4324 Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Tue, 13 Apr 2021 17:54:42 +0300 Subject: [PATCH 26/43] [SSE mobile] added controller for private code --- apps/spreadsheeteditor/mobile/src/controller/Main.jsx | 3 +++ apps/spreadsheeteditor/mobile/src/lib/patch.jsx | 6 ++++++ 2 files changed, 9 insertions(+) create mode 100644 apps/spreadsheeteditor/mobile/src/lib/patch.jsx diff --git a/apps/spreadsheeteditor/mobile/src/controller/Main.jsx b/apps/spreadsheeteditor/mobile/src/controller/Main.jsx index 5a1a6e8cb..1e166bd36 100644 --- a/apps/spreadsheeteditor/mobile/src/controller/Main.jsx +++ b/apps/spreadsheeteditor/mobile/src/controller/Main.jsx @@ -5,6 +5,7 @@ import { f7 } from 'framework7-react'; import { withTranslation } from 'react-i18next'; import CollaborationController from '../../../../common/mobile/lib/controller/collaboration/Collaboration.jsx' import { onAdvancedOptions } from './settings/Download.jsx'; +import EditorUIController from '../lib/patch'; import { AddCommentController, CommentsController, @@ -51,6 +52,8 @@ class MainController extends Component { }; const loadConfig = data => { + EditorUIController.isSupportEditFeature(); + let me = this; me.editorConfig = Object.assign({}, this.editorConfig, data.config); diff --git a/apps/spreadsheeteditor/mobile/src/lib/patch.jsx b/apps/spreadsheeteditor/mobile/src/lib/patch.jsx new file mode 100644 index 000000000..ec7b37a2c --- /dev/null +++ b/apps/spreadsheeteditor/mobile/src/lib/patch.jsx @@ -0,0 +1,6 @@ + +const EditorUIController = () => null; + +EditorUIController.isSupportEditFeature = () => false; + +export default EditorUIController; From eb6a25140da185e23f616a10cd8e9101c8c2f692 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Tue, 13 Apr 2021 18:23:37 +0300 Subject: [PATCH 27/43] [DE mobile] Add check to hide review in collaboration --- apps/common/mobile/lib/view/collaboration/Collaboration.jsx | 5 +++-- apps/documenteditor/mobile/src/store/appOptions.js | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/common/mobile/lib/view/collaboration/Collaboration.jsx b/apps/common/mobile/lib/view/collaboration/Collaboration.jsx index dde8d8f34..8511f9c85 100644 --- a/apps/common/mobile/lib/view/collaboration/Collaboration.jsx +++ b/apps/common/mobile/lib/view/collaboration/Collaboration.jsx @@ -87,6 +87,7 @@ const routes = [ const PageCollaboration = inject('storeAppOptions')(observer(props => { const { t } = useTranslation(); const _t = t('Common.Collaboration', {returnObjects: true}); + const appOptions = props.storeAppOptions; return ( @@ -103,12 +104,12 @@ const PageCollaboration = inject('storeAppOptions')(observer(props => { - {props.storeAppOptions.canViewComments && + {appOptions.canViewComments && } - {window.editorType === 'de' && + {window.editorType === 'de' && (appOptions.canReview || appOptions.canViewReview) && diff --git a/apps/documenteditor/mobile/src/store/appOptions.js b/apps/documenteditor/mobile/src/store/appOptions.js index f3bb99b12..b69972560 100644 --- a/apps/documenteditor/mobile/src/store/appOptions.js +++ b/apps/documenteditor/mobile/src/store/appOptions.js @@ -8,6 +8,8 @@ export class storeAppOptions { canReview: observable, setConfigOptions: action, setPermissionOptions: action, + + canViewReview: observable, setCanViewReview: action, lostEditingRights: observable, @@ -21,6 +23,7 @@ export class storeAppOptions { isEdit = false; canViewComments = false; canReview = false; + canViewReview = false; lostEditingRights = false; changeEditingRights (value) { From 87fb7fe1bd9a632f373c22c4b2d8b002dc75e804 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Wed, 14 Apr 2021 20:27:33 +0300 Subject: [PATCH 28/43] [DE mobile] Add check to show logo in navbar --- apps/common/mobile/resources/less/common.less | 14 ++++++++++--- apps/documenteditor/mobile/src/page/main.jsx | 21 ++++++++++++------- .../mobile/src/store/appOptions.js | 6 +++++- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/apps/common/mobile/resources/less/common.less b/apps/common/mobile/resources/less/common.less index 932563c7d..cb7c5f682 100644 --- a/apps/common/mobile/resources/less/common.less +++ b/apps/common/mobile/resources/less/common.less @@ -9,7 +9,10 @@ @autoColor: @black; .navbar.main-navbar { - height: 26px; + height: 0; + &.navbar-with-logo { + height: 26px; + } .navbar-inner { display: flex; justify-content: center; @@ -22,8 +25,13 @@ } } -.page.page-with-subnavbar .page-content { - --f7-page-subnavbar-offset: 26px; +.page.page-with-subnavbar { + .page-content { + --f7-page-subnavbar-offset: 0px; + } + &.page-with-logo .page-content { + --f7-page-subnavbar-offset: 26px; + } } .popup, .popover, .sheet-modal { diff --git a/apps/documenteditor/mobile/src/page/main.jsx b/apps/documenteditor/mobile/src/page/main.jsx index 6c4586868..89125f721 100644 --- a/apps/documenteditor/mobile/src/page/main.jsx +++ b/apps/documenteditor/mobile/src/page/main.jsx @@ -2,7 +2,7 @@ import React, { Component } from 'react'; import { f7 } from 'framework7-react'; import { Page, View, Navbar, Subnavbar, Icon } from 'framework7-react'; -import { inject } from "mobx-react"; +import { observer, inject } from "mobx-react"; import EditOptions from '../view/edit/Edit'; import AddOptions from '../view/add/Add'; @@ -13,7 +13,7 @@ import { Search, SearchSettings } from '../controller/Search'; import ContextMenu from '../controller/ContextMenu'; import { Toolbar } from "../controller/Toolbar"; -export default class MainPage extends Component { +class MainPage extends Component { constructor(props) { super(props); this.state = { @@ -62,14 +62,17 @@ export default class MainPage extends Component { }; render() { + const appOptions = this.props.storeAppOptions; + const config = appOptions.config; + const showLogo = !(appOptions.canBrandingExt && (config.customization && (config.customization.loaderName || config.customization.loaderLogo))); return ( - + {/* Top Navbar */} - -
+ + {showLogo &&
} - - + +
{/* Page content */} @@ -100,4 +103,6 @@ export default class MainPage extends Component {
) } -}; \ No newline at end of file +} + +export default inject("storeAppOptions")(observer(MainPage)); \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/store/appOptions.js b/apps/documenteditor/mobile/src/store/appOptions.js index b69972560..f0e5ddcdf 100644 --- a/apps/documenteditor/mobile/src/store/appOptions.js +++ b/apps/documenteditor/mobile/src/store/appOptions.js @@ -16,7 +16,9 @@ export class storeAppOptions { changeEditingRights: action, readerMode: observable, - changeReaderMode: action + changeReaderMode: action, + + canBrandingExt: observable }); } @@ -35,6 +37,8 @@ export class storeAppOptions { this.readerMode = !this.readerMode; } + canBrandingExt = false; + config = {}; setConfigOptions (config) { this.config = config; From 0277ac930611db0637100a2c5e6891ea495610a8 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Thu, 15 Apr 2021 12:42:44 +0300 Subject: [PATCH 29/43] [PE mobile] Add toolbar, add logo --- .../resources/less/common-material.less | 20 +- apps/common/mobile/resources/less/common.less | 6 + .../mobile/src/controller/Toolbar.jsx | 2 + .../mobile/src/less/app-material.less | 8 - .../mobile/src/controller/Main.jsx | 24 +- .../mobile/src/controller/Toolbar.jsx | 209 ++++++++++++++++++ .../mobile/src/page/main.jsx | 40 ++-- .../mobile/src/view/Toolbar.jsx | 35 +++ 8 files changed, 303 insertions(+), 41 deletions(-) create mode 100644 apps/presentationeditor/mobile/src/controller/Toolbar.jsx create mode 100644 apps/presentationeditor/mobile/src/view/Toolbar.jsx diff --git a/apps/common/mobile/resources/less/common-material.less b/apps/common/mobile/resources/less/common-material.less index a1a938939..4bec965e1 100644 --- a/apps/common/mobile/resources/less/common-material.less +++ b/apps/common/mobile/resources/less/common-material.less @@ -7,6 +7,17 @@ @darkGrey: #757575; --f7-navbar-shadow-image: none; + + --f7-navbar-bg-color: @themeColor; + --f7-navbar-link-color: @navBarIconColor; + --f7-navbar-text-color: @navBarIconColor; + --f7-navbar-height: 56px; + + --f7-subnavbar-bg-color: @themeColor; + --f7-subnavbar-link-color: @navBarIconColor; + --f7-subnavbar-text-color: @navBarIconColor; + --f7-subnavbar-height: 56px; + --f7-radio-active-color: @themeColor; --f7-toggle-active-color: @themeColor; --f7-range-bar-active-bg-color: @themeColor; @@ -29,6 +40,13 @@ justify-content: center; } } + + .page.page-with-subnavbar.page-with-logo { + .page-content { + --f7-page-navbar-offset: var(--f7-navbar-height); + } + } + // Buttons .segmented { .decrement, .increment { @@ -412,7 +430,7 @@ } a.icon-only { width: auto; - height: 48px; + height: 56px; } .buttons-row-replace a { color: @white; diff --git a/apps/common/mobile/resources/less/common.less b/apps/common/mobile/resources/less/common.less index cb7c5f682..77b45d5c3 100644 --- a/apps/common/mobile/resources/less/common.less +++ b/apps/common/mobile/resources/less/common.less @@ -25,6 +25,12 @@ } } +.subnavbar { + .subnavbar-inner { + padding: 0; + } +} + .page.page-with-subnavbar { .page-content { --f7-page-subnavbar-offset: 0px; diff --git a/apps/documenteditor/mobile/src/controller/Toolbar.jsx b/apps/documenteditor/mobile/src/controller/Toolbar.jsx index 9ff6ce8e8..30d47b86b 100644 --- a/apps/documenteditor/mobile/src/controller/Toolbar.jsx +++ b/apps/documenteditor/mobile/src/controller/Toolbar.jsx @@ -25,6 +25,7 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeReview')(prop Common.Notifications.on('api:disconnect', onCoAuthoringDisconnect); Common.Notifications.on('toolbar:activatecontrols', activateControls); Common.Notifications.on('toolbar:deactivateeditcontrols', deactivateEditControls); + Common.Notifications.on('goback', goBack); }; if ( !Common.EditorApi ) { Common.Notifications.on('document:ready', onDocumentReady); @@ -40,6 +41,7 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeReview')(prop Common.Notifications.off('api:disconnect', onCoAuthoringDisconnect); Common.Notifications.off('toolbar:activatecontrols', activateControls); Common.Notifications.off('toolbar:deactivateeditcontrols', deactivateEditControls); + Common.Notifications.off('goback', goBack); const api = Common.EditorApi.get(); api.asc_unregisterCallback('asc_onCanUndo', onApiCanUndo); diff --git a/apps/documenteditor/mobile/src/less/app-material.less b/apps/documenteditor/mobile/src/less/app-material.less index 4515f7854..981437364 100644 --- a/apps/documenteditor/mobile/src/less/app-material.less +++ b/apps/documenteditor/mobile/src/less/app-material.less @@ -5,14 +5,6 @@ .device-android { - --f7-navbar-bg-color: @themeColor; - --f7-navbar-link-color: @navBarIconColor; - --f7-navbar-text-color: @navBarIconColor; - - --f7-subnavbar-bg-color: @themeColor; - --f7-subnavbar-link-color: @navBarIconColor; - --f7-subnavbar-text-color: @navBarIconColor; - // Main Toolbar #editor-navbar.navbar .right { padding-right: 4px; diff --git a/apps/presentationeditor/mobile/src/controller/Main.jsx b/apps/presentationeditor/mobile/src/controller/Main.jsx index 1c7a9bd9b..aa3736bb3 100644 --- a/apps/presentationeditor/mobile/src/controller/Main.jsx +++ b/apps/presentationeditor/mobile/src/controller/Main.jsx @@ -105,13 +105,9 @@ class MainController extends Component { // Common.SharedSettings.set('document', data.doc); - // if (data.doc) { - // DE.getController('Toolbar').setDocumentTitle(data.doc.title); - // if (data.doc.info) { - // data.doc.info.author && console.log("Obsolete: The 'author' parameter of the document 'info' section is deprecated. Please use 'owner' instead."); - // data.doc.info.created && console.log("Obsolete: The 'created' parameter of the document 'info' section is deprecated. Please use 'uploaded' instead."); - // } - // } + if (data.doc) { + Common.Notifications.trigger('setdoctitle', data.doc.title); + } }; const onEditorPermissions = params => { @@ -335,13 +331,14 @@ class MainController extends Component { } _onDocumentContentReady() { - const me = this; - me.api.SetDrawingFreeze(false); + this.api.SetDrawingFreeze(false); - me.api.Resize(); - me.api.zoomFitToPage(); + this.api.Resize(); + this.api.zoomFitToPage(); // me.api.asc_GetDefaultTableStyles && _.defer(function () {me.api.asc_GetDefaultTableStyles()}); + this.applyLicense(); + Common.Gateway.documentReady(); f7.emit('resize'); @@ -357,6 +354,11 @@ class MainController extends Component { // } } + applyLicense() { + /* TO DO */ + Common.Notifications.trigger('toolbar:activatecontrols'); + } + render() { return ( diff --git a/apps/presentationeditor/mobile/src/controller/Toolbar.jsx b/apps/presentationeditor/mobile/src/controller/Toolbar.jsx new file mode 100644 index 000000000..d92f94f4a --- /dev/null +++ b/apps/presentationeditor/mobile/src/controller/Toolbar.jsx @@ -0,0 +1,209 @@ +import React, { useEffect, useState } from 'react'; +import { inject } from 'mobx-react'; +import { f7 } from 'framework7-react'; +import { useTranslation } from 'react-i18next'; +import ToolbarView from "../view/Toolbar"; + +const ToolbarController = inject('storeAppOptions', 'users')(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; + + useEffect(() => { + const onDocumentReady = () => { + const api = Common.EditorApi.get(); + api.asc_registerCallback('asc_onCanUndo', onApiCanUndo); + api.asc_registerCallback('asc_onCanRedo', onApiCanRedo); + api.asc_registerCallback('asc_onFocusObject', onApiFocusObject); + api.asc_registerCallback('asc_onCoAuthoringDisconnect', onCoAuthoringDisconnect); + api.asc_registerCallback('asc_onCountPages', onApiCountPages); + Common.Notifications.on('api:disconnect', onCoAuthoringDisconnect); + Common.Notifications.on('toolbar:activatecontrols', activateControls); + Common.Notifications.on('toolbar:deactivateeditcontrols', deactivateEditControls); + Common.Notifications.on('goback', goBack); + }; + if ( !Common.EditorApi ) { + Common.Notifications.on('document:ready', onDocumentReady); + Common.Notifications.on('setdoctitle', setDocTitle); + Common.Gateway.on('init', loadConfig); + } else { + onDocumentReady(); + } + + return () => { + 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); + Common.Notifications.off('goback', goBack); + + const api = Common.EditorApi.get(); + api.asc_unregisterCallback('asc_onCanUndo', onApiCanUndo); + api.asc_unregisterCallback('asc_onCanRedo', onApiCanRedo); + api.asc_unregisterCallback('asc_onFocusObject', onApiFocusObject); + api.asc_unregisterCallback('asc_onCoAuthoringDisconnect', onCoAuthoringDisconnect); + api.asc_unregisterCallback('asc_onCountPages', onApiCountPages); + } + }); + + const [docTitle, resetDocTitle] = useState(''); + const setDocTitle = (title) => { + resetDocTitle(title); + } + + // Back button + const [isShowBack, setShowBack] = useState(false); + const loadConfig = (data) => { + if (data && data.config && data.config.canBackToFolder !== false && + data.config.customization && data.config.customization.goback && + (data.config.customization.goback.url || data.config.customization.goback.requestClose && data.config.canRequestClose)) { + setShowBack(true); + } + }; + const onBack = () => { + const api = Common.EditorApi.get(); + if (api.isDocumentModified()) { + f7.dialog.create({ + title : _t.dlgLeaveTitleText, + text : _t.dlgLeaveMsgText, + verticalButtons: true, + buttons : [ + { + text: _t.leaveButtonText, + onClick: function() { + goBack(); + } + }, + { + text: _t.stayButtonText, + bold: true + } + ] + }).open(); + } else { + goBack(); + } + }; + const goBack = (current) => { + //if ( !Common.Controllers.Desktop.process('goback') ) { + if (appOptions.customization.goback.requestClose && appOptions.canRequestClose) { + Common.Gateway.requestClose(); + } else { + const href = appOptions.customization.goback.url; + if (!current && appOptions.customization.goback.blank !== false) { + window.open(href, "_blank"); + } else { + parent.location.href = href; + } + } + //} + } + + // Undo and Redo + const [isCanUndo, setCanUndo] = useState(true); + const [isCanRedo, setCanRedo] = useState(true); + const onApiCanUndo = (can) => { + if (isDisconnected) return; + setCanUndo(can); + }; + const onApiCanRedo = (can) => { + if (isDisconnected) return; + setCanRedo(can); + }; + const onUndo = () => { + const api = Common.EditorApi.get(); + if (api) { + api.Undo(); + } + }; + const onRedo = () => { + const api = Common.EditorApi.get(); + if (api) { + api.Redo(); + } + } + + const [disabledAdd, setDisabledAdd] = useState(false); + const [disabledEdit, setDisabledEdit] = useState(false); + const onApiFocusObject = (objects) => { + if (isDisconnected) return; + + if (objects.length > 0) { + let slide_deleted = false, + slide_lock = false, + no_object = true, + objectLocked = false; + objects.forEach((object) => { + const type = object.get_ObjectType(); + const objectValue = object.get_ObjectValue(); + if (type === Asc.c_oAscTypeSelectElement.Slide) { + slide_deleted = objectValue.get_LockDelete(); + slide_lock = objectValue.get_LockLayout() || objectValue.get_LockBackground() || objectValue.get_LockTransition() || objectValue.get_LockTiming(); + } else if (objectValue && typeof objectValue.get_Locked === 'function') { + no_object = false; + objectLocked = objectLocked || objectValue.get_Locked(); + } + }); + + setDisabledAdd(slide_deleted); + setDisabledEdit(slide_deleted || (objectLocked || no_object) && slide_lock); + } + }; + + const [disabledPreview, setDisabledPreview] = useState(false); + const onApiCountPages = (count) => { + setDisabledPreview(count <= 0); + }; + + const [disabledEditControls, setDisabledEditControls] = useState(false); + const [disabledSettings, setDisabledSettings] = useState(false); + const deactivateEditControls = (enableDownload) => { + setDisabledEditControls(true); + if (enableDownload) { + //DE.getController('Settings').setMode({isDisconnected: true, enableDownload: enableDownload}); + } else { + setDisabledSettings(true); + } + }; + + + const [disabledControls, setDisabledControls] = useState(true); + const activateControls = () => { + setDisabledControls(false); + }; + + const onCoAuthoringDisconnect = (enableDownload) => { + deactivateEditControls(enableDownload); + setCanUndo(false); + setCanRedo(false); + f7.popover.close(); + f7.sheet.close(); + f7.popup.close(); + }; + + return ( + + ) +}); + +export {ToolbarController as Toolbar}; \ No newline at end of file diff --git a/apps/presentationeditor/mobile/src/page/main.jsx b/apps/presentationeditor/mobile/src/page/main.jsx index 3a3d2f4cf..9f80b19cb 100644 --- a/apps/presentationeditor/mobile/src/page/main.jsx +++ b/apps/presentationeditor/mobile/src/page/main.jsx @@ -1,15 +1,16 @@ import React, { Component } from 'react'; -import { Page, View, Navbar, NavLeft, NavRight, Link, Icon } from 'framework7-react'; +import { Page, View, Navbar, Subnavbar, Icon } from 'framework7-react'; +import { observer, inject } from "mobx-react"; import EditOptions from '../view/edit/Edit'; import AddOptions from '../view/add/Add'; import Settings from '../view/settings/Settings'; import CollaborationView from '../../../../common/mobile/lib/view/collaboration/Collaboration.jsx'; -import { Device } from '../../../../common/mobile/utils/device'; import { Search, SearchSettings } from '../controller/Search'; import ContextMenu from '../controller/ContextMenu'; +import { Toolbar } from "../controller/Toolbar"; -export default class MainPage extends Component { +class MainPage extends Component { constructor(props) { super(props); this.state = { @@ -54,23 +55,18 @@ export default class MainPage extends Component { }; render() { - return ( - + const appOptions = this.props.storeAppOptions; + const config = appOptions.config; + const showLogo = !(appOptions.canBrandingExt && (config.customization && (config.customization.loaderName || config.customization.loaderLogo))); + return ( + {/* Top Navbar */} - - {/*
*/} - - - - - - this.handleClickToOpenOptions('edit')}> - this.handleClickToOpenOptions('add')}> - { Device.phone ? null : } - this.handleClickToOpenOptions('coauth')}> - this.handleClickToOpenOptions('settings')}> - - + + {showLogo &&
} + + + +
{/* Page content */} @@ -94,7 +90,9 @@ export default class MainPage extends Component { } -
+
) } -}; \ No newline at end of file +} + +export default inject("storeAppOptions")(observer(MainPage)); \ No newline at end of file diff --git a/apps/presentationeditor/mobile/src/view/Toolbar.jsx b/apps/presentationeditor/mobile/src/view/Toolbar.jsx new file mode 100644 index 000000000..89d0ebefa --- /dev/null +++ b/apps/presentationeditor/mobile/src/view/Toolbar.jsx @@ -0,0 +1,35 @@ +import React, {Fragment} from 'react'; +import {NavLeft, NavRight, NavTitle, Link, Icon} from 'framework7-react'; +import { Device } from '../../../../common/mobile/utils/device'; +import EditorUIController from '../lib/patch' + +const ToolbarView = props => { + return ( + + + {props.isShowBack && } + {props.isEdit && EditorUIController.getUndoRedo({ + disabledUndo: !props.isCanUndo, + disabledRedo: !props.isCanRedo, + onUndoClick: props.onUndo, + onRedoClick: props.onRedo + })} + + {!Device.phone && {props.docTitle}} + + + {props.isEdit && EditorUIController.getToolbarOptions({ + disabledAdd: props.disabledAdd || props.disabledControls, + disabledEdit: props.disabledEdit || props.disabledControls, + onEditClick: () => props.openOptions('edit'), + onAddClick: () => props.openOptions('add') + })} + { Device.phone ? null : } + {props.displayCollaboration && props.openOptions('coauth')}>} + props.openOptions('settings')}> + + + ) +}; + +export default ToolbarView; \ No newline at end of file From 9e753e6962391f96390dd88c9ee9c5f73b3d06d9 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Thu, 15 Apr 2021 12:43:24 +0300 Subject: [PATCH 30/43] [mobile] Fix error --- vendor/framework7-react/build/webpack.config.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vendor/framework7-react/build/webpack.config.js b/vendor/framework7-react/build/webpack.config.js index 9149edcf8..426a85f41 100644 --- a/vendor/framework7-react/build/webpack.config.js +++ b/vendor/framework7-react/build/webpack.config.js @@ -79,6 +79,8 @@ module.exports = { resolvePath('node_modules/ssr-window'), resolvePath('../../../web-apps-mobile/word'), + resolvePath('../../../web-apps-mobile/slide'), + resolvePath('../../../web-apps-mobile/cell') ], }, From 8912a1feabee616c693862fc90b9eaf2098f1784 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Thu, 15 Apr 2021 13:06:10 +0300 Subject: [PATCH 31/43] [PE mobile] Add files for preview --- .../mobile/src/controller/Preview.jsx | 17 +++++++++++++++++ .../presentationeditor/mobile/src/page/main.jsx | 12 +++++++++++- .../mobile/src/view/Preview.jsx | 10 ++++++++++ .../mobile/src/view/Toolbar.jsx | 2 +- 4 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 apps/presentationeditor/mobile/src/controller/Preview.jsx create mode 100644 apps/presentationeditor/mobile/src/view/Preview.jsx diff --git a/apps/presentationeditor/mobile/src/controller/Preview.jsx b/apps/presentationeditor/mobile/src/controller/Preview.jsx new file mode 100644 index 000000000..babf81120 --- /dev/null +++ b/apps/presentationeditor/mobile/src/controller/Preview.jsx @@ -0,0 +1,17 @@ +import React, { useEffect, useState } from 'react'; +import { inject } from 'mobx-react'; +import { f7 } from 'framework7-react'; +import { useTranslation } from 'react-i18next'; +import Preview from "../view/Preview"; + +const PreviewController = () => { + console.log('preview'); + return ( + + ) +}; + +export {PreviewController as Preview}; + + + diff --git a/apps/presentationeditor/mobile/src/page/main.jsx b/apps/presentationeditor/mobile/src/page/main.jsx index 9f80b19cb..e5e86581a 100644 --- a/apps/presentationeditor/mobile/src/page/main.jsx +++ b/apps/presentationeditor/mobile/src/page/main.jsx @@ -6,6 +6,7 @@ import EditOptions from '../view/edit/Edit'; import AddOptions from '../view/add/Add'; import Settings from '../view/settings/Settings'; import CollaborationView from '../../../../common/mobile/lib/view/collaboration/Collaboration.jsx'; +import { Preview } from "../controller/Preview"; import { Search, SearchSettings } from '../controller/Search'; import ContextMenu from '../controller/ContextMenu'; import { Toolbar } from "../controller/Toolbar"; @@ -18,6 +19,7 @@ class MainPage extends Component { addOptionsVisible: false, settingsVisible: false, collaborationVisible: false, + previewVisible: false }; } @@ -35,7 +37,9 @@ class MainPage extends Component { else if ( opts == 'settings' ) return {settingsVisible: true}; else if ( opts == 'coauth' ) - return {collaborationVisible: true} + return {collaborationVisible: true}; + else if ( opts == 'preview' ) + return {previewVisible: true}; }); }; @@ -50,6 +54,8 @@ class MainPage extends Component { return {settingsVisible: false}; else if ( opts == 'coauth' ) return {collaborationVisible: false} + else if ( opts == 'preview' ) + return {previewVisible: false}; }) })(); }; @@ -89,6 +95,10 @@ class MainPage extends Component { !this.state.collaborationVisible ? null : } + { + !this.state.previewVisible ? null : + + }
) diff --git a/apps/presentationeditor/mobile/src/view/Preview.jsx b/apps/presentationeditor/mobile/src/view/Preview.jsx new file mode 100644 index 000000000..5faae5f1a --- /dev/null +++ b/apps/presentationeditor/mobile/src/view/Preview.jsx @@ -0,0 +1,10 @@ +import React from 'react'; + +const Preview = () => { + return ( + <> + + ) +}; + +export default Preview; \ No newline at end of file diff --git a/apps/presentationeditor/mobile/src/view/Toolbar.jsx b/apps/presentationeditor/mobile/src/view/Toolbar.jsx index 89d0ebefa..8251fd2b0 100644 --- a/apps/presentationeditor/mobile/src/view/Toolbar.jsx +++ b/apps/presentationeditor/mobile/src/view/Toolbar.jsx @@ -17,7 +17,7 @@ const ToolbarView = props => { {!Device.phone && {props.docTitle}} - + {props.openOptions('preview')}}> {props.isEdit && EditorUIController.getToolbarOptions({ disabledAdd: props.disabledAdd || props.disabledControls, disabledEdit: props.disabledEdit || props.disabledControls, From c49fc13b80f3b8b4c38cd0f4b7112c6f68a4842e Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Thu, 15 Apr 2021 15:42:51 +0300 Subject: [PATCH 32/43] [DE mobile] Fix show context menu items for view mode --- .../mobile/src/controller/ContextMenu.jsx | 78 ++++++++++++++----- 1 file changed, 60 insertions(+), 18 deletions(-) diff --git a/apps/documenteditor/mobile/src/controller/ContextMenu.jsx b/apps/documenteditor/mobile/src/controller/ContextMenu.jsx index aedb54c99..978afa679 100644 --- a/apps/documenteditor/mobile/src/controller/ContextMenu.jsx +++ b/apps/documenteditor/mobile/src/controller/ContextMenu.jsx @@ -73,17 +73,27 @@ class ContextMenu extends ContextMenuController { case 'cut': if ( !LocalStorage.getBool("de-hide-copy-cut-paste-warning") ) this.showCopyCutPasteModal(); - break; case 'copy': - if ( !LocalStorage.getBool("de-hide-copy-cut-paste-warning") ) + if (!api.Copy() && !LocalStorage.getBool("de-hide-copy-cut-paste-warning") ) this.showCopyCutPasteModal(); - break; case 'paste': if ( !LocalStorage.getBool("de-hide-copy-cut-paste-warning") ) this.showCopyCutPasteModal(); - + break; + case 'viewcomment': + Common.Notifications.trigger('viewcomment'); + break; + case 'openlink': + const stack = api.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; case 'review': setTimeout(() => { @@ -95,19 +105,6 @@ class ContextMenu extends ContextMenuController { this.props.openOptions('coauth', 'cm-review-change'); }, 400); break; - case 'split': - this.showSplitModal(); - break; - case 'edit': - setTimeout(() => { - this.props.openOptions('edit'); - }, 0); - break; - case 'addlink': - setTimeout(() => { - this.props.openOptions('add', 'link'); - }, 400); - break; } console.log("click context menu item: " + action); @@ -206,8 +203,53 @@ class ContextMenu extends ContextMenuController { initMenuItems() { if ( !Common.EditorApi ) return []; + const { isEdit } = this.props; - return EditorUIController.ContextMenu.mapMenuItems(this); + if (isEdit) { + return EditorUIController.ContextMenu.mapMenuItems(this); + } else { + const { t } = this.props; + const _t = t("ContextMenu", {returnObjects: true}); + const { canViewComments } = this.props; + + const api = Common.EditorApi.get(); + const stack = api.getSelectedElements(); + const canCopy = api.can_CopyCut(); + + let itemsIcon = [], + itemsText = []; + + if ( canCopy ) { + itemsIcon.push({ + event: 'copy', + icon: 'icon-copy' + }); + } + + if ( canViewComments && this.isComments ) { + itemsText.push({ + caption: _t.menuViewComment, + event: 'viewcomment' + }); + } + + 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 itemsIcon.concat(itemsText); + } } initExtraItems () { From fe1a9e16d3c18cb5e9c2cc1aa512649c348aa283 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Fri, 16 Apr 2021 13:34:05 +0300 Subject: [PATCH 33/43] [PE mobile] Changes for private branch --- .../mobile/src/controller/ContextMenu.jsx | 217 ++++++------------ .../mobile/src/controller/Main.jsx | 82 +------ .../mobile/src/store/focusObjects.js | 137 +---------- 3 files changed, 82 insertions(+), 354 deletions(-) diff --git a/apps/presentationeditor/mobile/src/controller/ContextMenu.jsx b/apps/presentationeditor/mobile/src/controller/ContextMenu.jsx index 0db776dcc..b4680f6a0 100644 --- a/apps/presentationeditor/mobile/src/controller/ContextMenu.jsx +++ b/apps/presentationeditor/mobile/src/controller/ContextMenu.jsx @@ -7,6 +7,7 @@ import { LocalStorage } from '../../../../common/mobile/utils/LocalStorage'; 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 => ({ isEdit: stores.storeAppOptions.isEdit, @@ -57,10 +58,13 @@ class ContextMenu extends ContextMenuController { onMenuItemClick(action) { super.onMenuItemClick(action); + if ( EditorUIController.ContextMenu.handleMenuItemClick(this, action) ) + return; + const api = Common.EditorApi.get(); switch (action) { case 'cut': - if (!api.Cut() && !LocalStorage.getBool("pe-hide-copy-cut-paste-warning")) { + if ( !LocalStorage.getBool("pe-hide-copy-cut-paste-warning")) { this.showCopyCutPasteModal(); } break; @@ -70,29 +74,13 @@ class ContextMenu extends ContextMenuController { } break; case 'paste': - if (!api.Paste() && !LocalStorage.getBool("pe-hide-copy-cut-paste-warning")) { + if ( !LocalStorage.getBool("pe-hide-copy-cut-paste-warning")) { this.showCopyCutPasteModal(); } break; - case 'addcomment': - Common.Notifications.trigger('addcomment'); - break; case 'viewcomment': Common.Notifications.trigger('viewcomment'); break; - case 'delete': - api.asc_Remove(); - break; - case 'edit': - setTimeout(() => { - this.props.openOptions('edit'); - }, 0); - break; - case 'addlink': - setTimeout(() => { - this.props.openOptions('add', 'link'); - }, 400) - break; case 'openlink': const stack = Common.EditorApi.get().getSelectedElements(); let value; @@ -104,8 +92,6 @@ class ContextMenu extends ContextMenuController { value && this.openLink(value); break; } - - console.log("click context menu item: " + action); } showCopyCutPasteModal() { @@ -154,152 +140,77 @@ class ContextMenu extends ContextMenuController { initMenuItems() { if ( !Common.EditorApi ) return []; - const { t } = this.props; - const _t = t("ContextMenu", { returnObjects: true }); + const { isEdit } = this.props; - const { isEdit, canViewComments, isDisconnected } = this.props; + if (isEdit) { + return EditorUIController.ContextMenu.mapMenuItems(this); + } else { + const { t } = this.props; + const _t = t("ContextMenu", { returnObjects: true }); - const api = Common.EditorApi.get(); - const stack = api.getSelectedElements(); - const canCopy = api.can_CopyCut(); + const { canViewComments, isDisconnected } = this.props; - let itemsIcon = [], - itemsText = []; + const api = Common.EditorApi.get(); + const stack = api.getSelectedElements(); + const canCopy = api.can_CopyCut(); - let isText = false, - isTable = false, - isImage = false, - isChart = false, - isShape = false, - isLink = false, - isSlide = false, - isObject = false; + let itemsIcon = [], + itemsText = []; - stack.forEach(item => { - const objectType = item.get_ObjectType(), - objectValue = item.get_ObjectValue(); + let isText = false, + isTable = false, + isImage = false, + isChart = false, + isShape = false, + isLink = false, + isSlide = false, + isObject = false; - if (objectType == Asc.c_oAscTypeSelectElement.Paragraph) { - isText = true; - } else if (objectType == Asc.c_oAscTypeSelectElement.Image) { - isImage = true; - } else if (objectType == Asc.c_oAscTypeSelectElement.Chart) { - isChart = true; - } else if (objectType == Asc.c_oAscTypeSelectElement.Shape) { - isShape = true; - } else if (objectType == Asc.c_oAscTypeSelectElement.Table) { - isTable = true; - } else if (objectType == Asc.c_oAscTypeSelectElement.Hyperlink) { - isLink = true; - } else if (objectType == Asc.c_oAscTypeSelectElement.Slide) { - isSlide = true; - } - }); + stack.forEach(item => { + const objectType = item.get_ObjectType(), + objectValue = item.get_ObjectValue(); - isObject = isText || isImage || isChart || isShape || isTable; - - if (canCopy && isObject) { - itemsIcon.push({ - event: 'copy', - icon: 'icon-copy' - }); - } - if (canViewComments && this.isComments && !isEdit) { - itemsText.push({ - caption: _t.menuViewComment, - event: 'viewcomment' - }); - } - - if ( stack.length > 0 ) { - let topObject = stack[stack.length - 1], - topObjectType = topObject.get_ObjectType(), - topObjectValue = topObject.get_ObjectValue(), - objectLocked = typeof topObjectValue.get_Locked === 'function' ? topObjectValue.get_Locked() : false; - - !objectLocked && (objectLocked = typeof topObjectValue.get_LockDelete === 'function' ? topObjectValue.get_LockDelete() : false); - - const swapItems = function(items, indexBefore, indexAfter) { - items[indexAfter] = items.splice(indexBefore, 1, items[indexAfter])[0]; - }; - - if (!objectLocked && isEdit && !isDisconnected) { - if (canCopy && isObject) { - itemsIcon.push({ - event: 'cut', - icon: 'icon-cut' - }); - - // Swap 'Copy' and 'Cut' - swapItems(itemsIcon, 0, 1); + if (objectType == Asc.c_oAscTypeSelectElement.Paragraph) { + isText = true; + } else if (objectType == Asc.c_oAscTypeSelectElement.Image) { + isImage = true; + } else if (objectType == Asc.c_oAscTypeSelectElement.Chart) { + isChart = true; + } else if (objectType == Asc.c_oAscTypeSelectElement.Shape) { + isShape = true; + } else if (objectType == Asc.c_oAscTypeSelectElement.Table) { + isTable = true; + } else if (objectType == Asc.c_oAscTypeSelectElement.Hyperlink) { + isLink = true; + } else if (objectType == Asc.c_oAscTypeSelectElement.Slide) { + isSlide = true; } + }); + isObject = isText || isImage || isChart || isShape || isTable; + + if (canCopy && isObject) { itemsIcon.push({ - event: 'paste', - icon: 'icon-paste' + event: 'copy', + icon: 'icon-copy' }); - - if (isObject) - itemsText.push({ - caption: _t.menuDelete, - event: 'delete' - }); - - itemsText.push({ - caption: _t.menuEdit, - event: 'edit' - }); - - if (!isLink && api.can_AddHyperlink() !== false) { - itemsText.push({ - caption: _t.menuAddLink, - event: 'addlink' - }); - } - - if (this.isComments && canViewComments) { - itemsText.push({ - caption: _t.menuViewComment, - event: 'viewcomment' - }); - } - - const hideAddComment = (isText && isChart) || api.can_AddQuotedComment() === false || !canViewComments; - if (!hideAddComment) { - itemsText.push({ - caption: _t.menuAddComment, - event: 'addcomment' - }); - } } + if (canViewComments && this.isComments && !isEdit) { + itemsText.push({ + caption: _t.menuViewComment, + event: 'viewcomment' + }); + } + + if (isLink) { + itemsText.push({ + caption: _t.menuOpenLink, + event: 'openlink' + }); + } + + return itemsIcon.concat(itemsText); } - - if (isLink) { - itemsText.push({ - caption: _t.menuOpenLink, - event: 'openlink' - }); - } - - - if ( Device.phone && itemsText.length > 2 ) { - this.extraItems = itemsText.splice(2,itemsText.length, { - caption: _t.menuMore, - event: 'showActionSheet' - }); - } - - return itemsIcon.concat(itemsText); - // return [{ - // caption: 'Edit', - // event: 'edit' - // }, { - // caption: 'View', - // event: 'view' - // }, { - // icon: 'icon-paste', - // event: 'review' - // }]; } initExtraItems () { diff --git a/apps/presentationeditor/mobile/src/controller/Main.jsx b/apps/presentationeditor/mobile/src/controller/Main.jsx index cc4a858b9..60e7b6eda 100644 --- a/apps/presentationeditor/mobile/src/controller/Main.jsx +++ b/apps/presentationeditor/mobile/src/controller/Main.jsx @@ -144,6 +144,8 @@ class MainController extends Component { 'translate': t('Controller.Main.SDK', {returnObjects:true}) }); + Common.EditorApi = {get: () => this.api}; + this.appOptions = {}; this.bindEvents(); @@ -160,7 +162,6 @@ class MainController extends Component { Common.Gateway.appReady(); Common.Notifications.trigger('engineCreated', this.api); - Common.EditorApi = {get: () => this.api}; }, error => { console.log('promise failed ' + error); }); @@ -174,89 +175,30 @@ class MainController extends Component { } bindEvents() { - const me = this; // me.api.asc_registerCallback('asc_onError', _.bind(me.onError, me)); - me.api.asc_registerCallback('asc_onDocumentContentReady', me._onDocumentContentReady.bind(me)); - me.api.asc_registerCallback('asc_onOpenDocumentProgress', me._onOpenDocumentProgress.bind(me)); + this.api.asc_registerCallback('asc_onDocumentContentReady', this._onDocumentContentReady.bind(this)); + this.api.asc_registerCallback('asc_onOpenDocumentProgress', this._onOpenDocumentProgress.bind(this)); const storePresentationSettings = this.props.storePresentationSettings; - me.api.asc_registerCallback('asc_onPresentationSize', (width, height) => { + this.api.asc_registerCallback('asc_onPresentationSize', (width, height) => { storePresentationSettings.changeSizeIndex(width, height); }); - me.api.asc_registerCallback('asc_onSendThemeColorSchemes', (arr) => { + this.api.asc_registerCallback('asc_onSendThemeColorSchemes', (arr) => { storePresentationSettings.addSchemes(arr); }); - // api.asc_registerCallback('asc_onSendThemeColorSchemes', _.bind(this.onSendThemeColorSchemes, this)); - // me.api.asc_registerCallback('asc_onDocumentUpdateVersion', _.bind(me.onUpdateVersion, me)); - // me.api.asc_registerCallback('asc_onServerVersion', _.bind(me.onServerVersion, me)); - // me.api.asc_registerCallback('asc_onAdvancedOptions', _.bind(me.onAdvancedOptions, me)); - // me.api.asc_registerCallback('asc_onDocumentName', _.bind(me.onDocumentName, me)); - // me.api.asc_registerCallback('asc_onPrintUrl', _.bind(me.onPrintUrl, me)); - // me.api.asc_registerCallback('asc_onThumbnailsShow', _.bind(me.onThumbnailsShow, me)); - // me.api.asc_registerCallback('asc_onMeta', _.bind(me.onMeta, me)); + EditorUIController.initFocusObjects(this.props.storeFocusObjects); - const storeFocusObjects = this.props.storeFocusObjects; - const storeSlideSettings = this.props.storeSlideSettings; - - this.api.asc_registerCallback('asc_onFocusObject', objects => { - // console.log(objects); - storeFocusObjects.resetFocusObjects(objects); - }); - - this.api.asc_registerCallback('asc_onInitEditorStyles', themes => { - // console.log(themes); - storeSlideSettings.addArrayThemes(themes); - }); - - this.api.asc_registerCallback('asc_onUpdateThemeIndex', themeId => { - // console.log(themeId); - storeSlideSettings.changeSlideThemeIndex(themeId); - }); - - this.api.asc_registerCallback('asc_onUpdateLayout', layouts => { - // console.log(layouts); - storeSlideSettings.addArrayLayouts(layouts); - }); - - this.api.asc_registerCallback('asc_onSendThemeColors', (colors, standart_colors) => { - Common.Utils.ThemeColor.setColors(colors, standart_colors); - }); + EditorUIController.initEditorStyles(this.props.storeSlideSettings); // Text settings const storeTextSettings = this.props.storeTextSettings; - this.api.asc_registerCallback('asc_onInitEditorFonts', (fonts, select) => { - storeTextSettings.initEditorFonts(fonts, select); - }); - - this.api.asc_registerCallback('asc_onFontFamily', (font) => { - storeTextSettings.resetFontName(font); - }); - - this.api.asc_registerCallback('asc_onFontSize', (size) => { - storeTextSettings.resetFontSize(size); - }); - - this.api.asc_registerCallback('asc_onBold', (isBold) => { - storeTextSettings.resetIsBold(isBold); - }); - - this.api.asc_registerCallback('asc_onItalic', (isItalic) => { - storeTextSettings.resetIsItalic(isItalic); - }); - - this.api.asc_registerCallback('asc_onUnderline', (isUnderline) => { - storeTextSettings.resetIsUnderline(isUnderline); - }); - - this.api.asc_registerCallback('asc_onStrikeout', (isStrikeout) => { - storeTextSettings.resetIsStrikeout(isStrikeout); - }); + EditorUIController.initFonts(storeTextSettings); this.api.asc_registerCallback('asc_onVerticalAlign', (typeBaseline) => { storeTextSettings.resetTypeBaseline(typeBaseline); @@ -315,11 +257,7 @@ class MainController extends Component { // Table settings - const storeTableSettings = this.props.storeTableSettings; - - this.api.asc_registerCallback('asc_onInitTableTemplates', (templates) => { - storeTableSettings.initTableTemplates(templates); - }); + EditorUIController.initTableTemplates(this.props.storeTableSettings); // Chart settings diff --git a/apps/presentationeditor/mobile/src/store/focusObjects.js b/apps/presentationeditor/mobile/src/store/focusObjects.js index 4ad5bafc1..2a363150a 100644 --- a/apps/presentationeditor/mobile/src/store/focusObjects.js +++ b/apps/presentationeditor/mobile/src/store/focusObjects.js @@ -25,79 +25,15 @@ export class storeFocusObjects { } get settings() { - const _settings = []; - let no_text = true; - for (let object of this._focusObjects) { - const type = object.get_ObjectType(), - objectValue = object.get_ObjectValue(); - if (Asc.c_oAscTypeSelectElement.Paragraph == type) { - if ( !objectValue.get_Locked() ) - no_text = false; - } else if (Asc.c_oAscTypeSelectElement.Table == type) { - if ( !objectValue.get_Locked() ) { - _settings.push('table'); - no_text = false; - } - } else if (Asc.c_oAscTypeSelectElement.Slide == type) { - if ( !(objectValue.get_LockLayout() || objectValue.get_LockBackground() || objectValue.get_LockTransition() || objectValue.get_LockTiming() )) - _settings.push('slide'); - } else if (Asc.c_oAscTypeSelectElement.Image == type) { - if ( !objectValue.get_Locked() ) - _settings.push('image'); - } else if (Asc.c_oAscTypeSelectElement.Chart == type) { - if ( !objectValue.get_Locked() ) - _settings.push('chart'); - } else if (Asc.c_oAscTypeSelectElement.Shape == type && !objectValue.get_FromChart()) { - if ( !objectValue.get_Locked() ) { - _settings.push('shape'); - no_text = false; - } - } else if (Asc.c_oAscTypeSelectElement.Hyperlink == type) { - _settings.push('hyperlink'); - } - } - if (!no_text && _settings.indexOf('image') < 0) - _settings.unshift('text'); - const resultArr = _settings.filter((value, index, self) => self.indexOf(value) === index); //get uniq array - // Exclude hyperlink if text is locked - if (resultArr.indexOf('hyperlink') > -1 && resultArr.indexOf('text') < 0) { - resultArr.splice(resultArr.indexOf('hyperlink'), 1); - } - // Exclude shapes if chart exist - if (resultArr.indexOf('chart') > -1 && resultArr.indexOf('shape') > -1) { - resultArr.splice(resultArr.indexOf('shape'), 1); - } - return resultArr; + return !!this.intf ? this.intf.filterFocusObjects() : null; } get slideObject() { - const slides = []; - for (let object of this._focusObjects) { - if (object.get_ObjectType() === Asc.c_oAscTypeSelectElement.Slide) { - slides.push(object); - } - } - if (slides.length > 0) { - const object = slides[slides.length - 1]; // get top - return object.get_ObjectValue(); - } else { - return undefined; - } + return !!this.intf ? this.intf.getSlideObject() : null; } get paragraphObject() { - const paragraphs = []; - for (let object of this._focusObjects) { - if (object.get_ObjectType() === Asc.c_oAscTypeSelectElement.Paragraph) { - paragraphs.push(object); - } - } - if (paragraphs.length > 0) { - const object = paragraphs[paragraphs.length - 1]; // get top - return object.get_ObjectValue(); - } else { - return undefined; - } + return !!this.intf ? this.intf.getParagraphObject() : null; } get paragraphLocked() { @@ -111,48 +47,15 @@ export class storeFocusObjects { } get shapeObject() { - const shapes = []; - for (let object of this._focusObjects) { - if (object.get_ObjectType() === Asc.c_oAscTypeSelectElement.Shape) { - shapes.push(object); - } - } - if (shapes.length > 0) { - const object = shapes[shapes.length - 1]; // get top - return object.get_ObjectValue(); - } else { - return undefined; - } + return !!this.intf ? this.intf.getShapeObject() : null; } get imageObject() { - const images = []; - for (let object of this._focusObjects) { - if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Image && object.get_ObjectValue()) { - images.push(object); - } - } - if (images.length > 0) { - const object = images[images.length - 1]; // get top - return object.get_ObjectValue(); - } else { - return undefined; - } + return !!this.intf ? this.intf.getImageObject() : null; } get tableObject() { - const tables = []; - for (let object of this._focusObjects) { - if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Table) { - tables.push(object); - } - } - if (tables.length > 0) { - const object = tables[tables.length - 1]; // get top table - return object.get_ObjectValue(); - } else { - return undefined; - } + return !!this.intf ? this.intf.getTableObject() : null; } get isTableInStack() { @@ -165,34 +68,10 @@ export class storeFocusObjects { } get chartObject() { - const charts = []; - - for (let object of this._focusObjects) { - if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Chart) { - charts.push(object); - } - } - - if (charts.length > 0) { - const object = charts[charts.length - 1]; // get top - return object.get_ObjectValue(); - } else { - return undefined; - } + return !!this.intf ? this.intf.getChartObject() : null; } get linkObject() { - const links = []; - for (let object of this._focusObjects) { - if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Hyperlink) { - links.push(object); - } - } - if (links.length > 0) { - const object = links[links.length - 1]; // get top - return object.get_ObjectValue(); - } else { - return undefined; - } + return !!this.intf ? this.intf.getLinkObject() : null; } } \ No newline at end of file From 1466cd61e4d4c4ecf0f75c24a25d90e5ec0777a5 Mon Sep 17 00:00:00 2001 From: SergeyEzhin Date: Fri, 16 Apr 2021 17:03:28 +0300 Subject: [PATCH 34/43] [PE mobile] Added preview slides --- apps/presentationeditor/mobile/locale/en.json | 3 +- .../mobile/src/controller/Preview.jsx | 94 ++++++++++++++++++- .../mobile/src/page/main.jsx | 93 +++++++++--------- .../mobile/src/view/Preview.jsx | 5 +- 4 files changed, 147 insertions(+), 48 deletions(-) diff --git a/apps/presentationeditor/mobile/locale/en.json b/apps/presentationeditor/mobile/locale/en.json index 2651a9ccf..bcf17b851 100644 --- a/apps/presentationeditor/mobile/locale/en.json +++ b/apps/presentationeditor/mobile/locale/en.json @@ -274,7 +274,8 @@ "textCaseSensitive": "Case Sensitive", "textHighlight": "Highlight Results", "textNoTextFound": "Text not Found", - "textSelectObjectToEdit": "Select object to edit" + "textSelectObjectToEdit": "Select object to edit", + "textFinalMessage": "The end of slide preview. Click to exit." } }, "Common": { diff --git a/apps/presentationeditor/mobile/src/controller/Preview.jsx b/apps/presentationeditor/mobile/src/controller/Preview.jsx index babf81120..b072f6638 100644 --- a/apps/presentationeditor/mobile/src/controller/Preview.jsx +++ b/apps/presentationeditor/mobile/src/controller/Preview.jsx @@ -4,8 +4,98 @@ import { f7 } from 'framework7-react'; import { useTranslation } from 'react-i18next'; import Preview from "../view/Preview"; -const PreviewController = () => { - console.log('preview'); +const PreviewController = props => { + const { t } = useTranslation(); + const _t = t('View.Edit', {returnObjects: true}) + + let _view, _touches, _touchStart, _touchEnd; + + _view = $$('#pe-preview'); + + useEffect(() => { + const onDocumentReady = () => { + const api = Common.EditorApi.get(); + + api.asc_registerCallback('asc_onEndDemonstration', onEndDemonstration); + api.DemonstrationEndShowMessage(_t.textFinalMessage); + }; + + show(); + onDocumentReady(); + + _view.on('touchstart', onTouchStart); + _view.on('touchmove', onTouchMove); + _view.on('touchend', onTouchEnd); + _view.on('click', onClick); + + return () => { + const api = Common.EditorApi.get(); + + api.asc_unregisterCallback('asc_onEndDemonstration', onEndDemonstration); + + _view.off('touchstart', onTouchStart); + _view.off('touchmove', onTouchMove); + _view.off('touchend', onTouchEnd); + _view.off('click', onClick); + }; + }, []); + + const show = () => { + const api = Common.EditorApi.get(); + api.StartDemonstration('presentation-preview', api.getCurrentPage()); + }; + + const onTouchStart = e => { + e.preventDefault(); + + _touches = []; + + for (let i = 0; i < e.touches.length; i++) { + _touches.push([e.touches[i].pageX, e.touches[i].pageY]); + } + _touchEnd = _touchStart = [e.touches[0].pageX, e.touches[0].pageY]; + }; + + const onTouchMove = e => { + e.preventDefault(); + + const api = Common.EditorApi.get(); + + _touchEnd = [e.touches[0].pageX, e.touches[0].pageY]; + + if (e.touches.length < 2 ) return; + + for (let i = 0; i < e.touches.length; i++) { + if (Math.abs(e.touches[i].pageX - _touches[i][0]) > 20 || Math.abs(e.touches[i].pageY - _touches[i][1]) > 20 ) { + api.EndDemonstration(); + break; + } + } + }; + + const onTouchEnd = e => { + e.preventDefault(); + + const api = Common.EditorApi.get(); + + if (_touchEnd[0] - _touchStart[0] > 20) + api.DemonstrationPrevSlide(); + else if (_touchStart[0] - _touchEnd[0] > 20) + api.DemonstrationNextSlide(); + }; + + const onClick = e => { + const api = Common.EditorApi.get(); + api.DemonstrationNextSlide(); + }; + + // API Handlers + + const onEndDemonstration = () => { + if(props.previewVisible) + props.onClosePreview(); + }; + return ( ) diff --git a/apps/presentationeditor/mobile/src/page/main.jsx b/apps/presentationeditor/mobile/src/page/main.jsx index e5e86581a..41ebdba85 100644 --- a/apps/presentationeditor/mobile/src/page/main.jsx +++ b/apps/presentationeditor/mobile/src/page/main.jsx @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { Component, Fragment } from 'react'; import { Page, View, Navbar, Subnavbar, Icon } from 'framework7-react'; import { observer, inject } from "mobx-react"; @@ -10,7 +10,6 @@ import { Preview } from "../controller/Preview"; import { Search, SearchSettings } from '../controller/Search'; import ContextMenu from '../controller/ContextMenu'; import { Toolbar } from "../controller/Toolbar"; - class MainPage extends Component { constructor(props) { super(props); @@ -23,6 +22,10 @@ class MainPage extends Component { }; } + onClosePreview = () => { + this.setState({previewVisible: false}); + } + handleClickToOpenOptions = (opts, showOpts) => { ContextMenu.closeContextMenu(); @@ -60,49 +63,53 @@ class MainPage extends Component { })(); }; - render() { - const appOptions = this.props.storeAppOptions; - const config = appOptions.config; - const showLogo = !(appOptions.canBrandingExt && (config.customization && (config.customization.loaderName || config.customization.loaderLogo))); - return ( - - {/* Top Navbar */} - - {showLogo &&
} - - - - -
- {/* Page content */} - + render() { + const appOptions = this.props.storeAppOptions; + const config = appOptions.config; + const showLogo = !(appOptions.canBrandingExt && (config.customization && (config.customization.loaderName || config.customization.loaderLogo))); - + return ( + + {this.state.previewVisible ? : null} + + {/* Top Navbar */} + + {showLogo &&
} + + + + +
+ {/* Page content */} + - { - !this.state.editOptionsVisible ? null : - - } - { - !this.state.addOptionsVisible ? null : - - } - { - !this.state.settingsVisible ? null : - - } - { - !this.state.collaborationVisible ? null : - - } - { - !this.state.previewVisible ? null : - - } - -
- ) - } + + + { + !this.state.editOptionsVisible ? null : + + } + { + !this.state.addOptionsVisible ? null : + + } + { + !this.state.settingsVisible ? null : + + } + { + !this.state.collaborationVisible ? null : + + } + { + !this.state.previewVisible ? null : + + } + +
+
+ ) + } } export default inject("storeAppOptions")(observer(MainPage)); \ No newline at end of file diff --git a/apps/presentationeditor/mobile/src/view/Preview.jsx b/apps/presentationeditor/mobile/src/view/Preview.jsx index 5faae5f1a..96a618b42 100644 --- a/apps/presentationeditor/mobile/src/view/Preview.jsx +++ b/apps/presentationeditor/mobile/src/view/Preview.jsx @@ -2,8 +2,9 @@ import React from 'react'; const Preview = () => { return ( - <> - +
+
+
) }; From 45a9058da461a9da67ccb389faad08bce8cbda55 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Fri, 16 Apr 2021 19:03:30 +0300 Subject: [PATCH 35/43] [DE PE mobile] Changes for private branch --- .../mobile/src/controller/ContextMenu.jsx | 4 +-- .../mobile/src/controller/Main.jsx | 25 ++++++------------- .../mobile/src/view/Toolbar.jsx | 4 +-- .../mobile/src/controller/ContextMenu.jsx | 4 +-- .../mobile/src/controller/Main.jsx | 21 ++++++---------- .../mobile/src/view/Toolbar.jsx | 4 +-- 6 files changed, 23 insertions(+), 39 deletions(-) diff --git a/apps/documenteditor/mobile/src/controller/ContextMenu.jsx b/apps/documenteditor/mobile/src/controller/ContextMenu.jsx index 978afa679..136679559 100644 --- a/apps/documenteditor/mobile/src/controller/ContextMenu.jsx +++ b/apps/documenteditor/mobile/src/controller/ContextMenu.jsx @@ -65,7 +65,7 @@ class ContextMenu extends ContextMenuController { onMenuItemClick(action) { super.onMenuItemClick(action); - if ( EditorUIController.ContextMenu.handleMenuItemClick(this, action) ) + if ( EditorUIController.ContextMenu && EditorUIController.ContextMenu.handleMenuItemClick(this, action) ) return; const api = Common.EditorApi.get(); @@ -205,7 +205,7 @@ class ContextMenu extends ContextMenuController { if ( !Common.EditorApi ) return []; const { isEdit } = this.props; - if (isEdit) { + if (isEdit && EditorUIController.ContextMenu) { return EditorUIController.ContextMenu.mapMenuItems(this); } else { const { t } = this.props; diff --git a/apps/documenteditor/mobile/src/controller/Main.jsx b/apps/documenteditor/mobile/src/controller/Main.jsx index c08ce978b..061f1eae9 100644 --- a/apps/documenteditor/mobile/src/controller/Main.jsx +++ b/apps/documenteditor/mobile/src/controller/Main.jsx @@ -9,8 +9,6 @@ import {InitReviewController as ReviewController} from '../../../../common/mobil import { onAdvancedOptions } from './settings/Download.jsx'; import { CommentsController, - AddCommentController, - EditCommentController, ViewCommentsController } from "../../../../common/mobile/lib/controller/collaboration/Comments"; import About from '../../../../common/mobile/lib/view/About'; @@ -488,9 +486,7 @@ class MainController extends Component { 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_onSendThemeColors', (colors, standart_colors) => { - Common.Utils.ThemeColor.setColors(colors, standart_colors); - }); + EditorUIController.initThemeColors && EditorUIController.initThemeColors(); this.api.asc_registerCallback('asc_onDownloadUrl', this.onDownloadUrl.bind(this)); @@ -504,8 +500,8 @@ class MainController extends Component { //text settings const storeTextSettings = this.props.storeTextSettings; - EditorUIController.initFonts(storeTextSettings); - EditorUIController.initFocusObjects(this.props.storeFocusObjects); + EditorUIController.initFonts && EditorUIController.initFonts(storeTextSettings); + EditorUIController.initFocusObjects && EditorUIController.initFocusObjects(this.props.storeFocusObjects); this.api.asc_registerCallback('asc_onVerticalAlign', (typeBaseline) => { storeTextSettings.resetTypeBaseline(typeBaseline); @@ -543,19 +539,13 @@ class MainController extends Component { }); //paragraph settings - EditorUIController.initEditorStyles(this.props.storeParagraphSettings); + EditorUIController.initEditorStyles && EditorUIController.initEditorStyles(this.props.storeParagraphSettings); //table settings - EditorUIController.initTableTemplates(this.props.storeTableSettings); + EditorUIController.initTableTemplates && EditorUIController.initTableTemplates(this.props.storeTableSettings); //chart settings - const storeChartSettings = this.props.storeChartSettings; - const storeFocusObjects = this.props.storeFocusObjects; - this.api.asc_registerCallback('asc_onUpdateChartStyles', () => { - if (storeFocusObjects.chartObject && storeFocusObjects.chartObject.get_ChartProperties()) { - storeChartSettings.updateChartStyles(this.api.asc_getChartPreviews(storeFocusObjects.chartObject.get_ChartProperties().getType())); - } - }); + EditorUIController.updateChartStyles && EditorUIController.updateChartStyles(this.props.storeChartSettings, this.props.storeFocusObjects); // Document Info @@ -782,8 +772,7 @@ class MainController extends Component { - - + {EditorUIController.getEditCommentControllers && EditorUIController.getEditCommentControllers()}
) diff --git a/apps/documenteditor/mobile/src/view/Toolbar.jsx b/apps/documenteditor/mobile/src/view/Toolbar.jsx index d73db145c..6dd921194 100644 --- a/apps/documenteditor/mobile/src/view/Toolbar.jsx +++ b/apps/documenteditor/mobile/src/view/Toolbar.jsx @@ -9,7 +9,7 @@ const ToolbarView = props => { {props.isShowBack && } - {props.isEdit && EditorUIController.getUndoRedo({ + {props.isEdit && EditorUIController.getUndoRedo && EditorUIController.getUndoRedo({ disabledUndo: !props.isCanUndo, disabledRedo: !props.isCanRedo, onUndoClick: props.onUndo, @@ -18,7 +18,7 @@ const ToolbarView = props => { {!Device.phone && {props.docTitle}} - {props.isEdit && EditorUIController.getToolbarOptions({ + {props.isEdit && EditorUIController.getToolbarOptions && EditorUIController.getToolbarOptions({ disabled: disableEditBtn || props.disabledControls, onEditClick: e => props.openOptions('edit'), onAddClick: e => props.openOptions('add') diff --git a/apps/presentationeditor/mobile/src/controller/ContextMenu.jsx b/apps/presentationeditor/mobile/src/controller/ContextMenu.jsx index b4680f6a0..e72ce5d66 100644 --- a/apps/presentationeditor/mobile/src/controller/ContextMenu.jsx +++ b/apps/presentationeditor/mobile/src/controller/ContextMenu.jsx @@ -58,7 +58,7 @@ class ContextMenu extends ContextMenuController { onMenuItemClick(action) { super.onMenuItemClick(action); - if ( EditorUIController.ContextMenu.handleMenuItemClick(this, action) ) + if ( EditorUIController.ContextMenu && EditorUIController.ContextMenu.handleMenuItemClick(this, action) ) return; const api = Common.EditorApi.get(); @@ -142,7 +142,7 @@ class ContextMenu extends ContextMenuController { const { isEdit } = this.props; - if (isEdit) { + if (isEdit && EditorUIController.ContextMenu) { return EditorUIController.ContextMenu.mapMenuItems(this); } else { const { t } = this.props; diff --git a/apps/presentationeditor/mobile/src/controller/Main.jsx b/apps/presentationeditor/mobile/src/controller/Main.jsx index 60e7b6eda..8c5e89e0b 100644 --- a/apps/presentationeditor/mobile/src/controller/Main.jsx +++ b/apps/presentationeditor/mobile/src/controller/Main.jsx @@ -180,6 +180,8 @@ class MainController extends Component { this.api.asc_registerCallback('asc_onDocumentContentReady', this._onDocumentContentReady.bind(this)); this.api.asc_registerCallback('asc_onOpenDocumentProgress', this._onOpenDocumentProgress.bind(this)); + EditorUIController.initThemeColors && EditorUIController.initThemeColors(); + const storePresentationSettings = this.props.storePresentationSettings; this.api.asc_registerCallback('asc_onPresentationSize', (width, height) => { @@ -190,15 +192,15 @@ class MainController extends Component { storePresentationSettings.addSchemes(arr); }); - EditorUIController.initFocusObjects(this.props.storeFocusObjects); + EditorUIController.initFocusObjects && EditorUIController.initFocusObjects(this.props.storeFocusObjects); - EditorUIController.initEditorStyles(this.props.storeSlideSettings); + EditorUIController.initEditorStyles && EditorUIController.initEditorStyles(this.props.storeSlideSettings); // Text settings const storeTextSettings = this.props.storeTextSettings; - EditorUIController.initFonts(storeTextSettings); + EditorUIController.initFonts && EditorUIController.initFonts(storeTextSettings); this.api.asc_registerCallback('asc_onVerticalAlign', (typeBaseline) => { storeTextSettings.resetTypeBaseline(typeBaseline); @@ -257,17 +259,11 @@ class MainController extends Component { // Table settings - EditorUIController.initTableTemplates(this.props.storeTableSettings); + EditorUIController.initTableTemplates && EditorUIController.initTableTemplates(this.props.storeTableSettings); // Chart settings - const storeChartSettings = this.props.storeChartSettings; - - this.api.asc_registerCallback('asc_onUpdateChartStyles', () => { - if (storeFocusObjects.chartObject) { - storeChartSettings.updateChartStyles(this.api.asc_getChartPreviews(storeFocusObjects.chartObject.getType())); - } - }); + EditorUIController.updateChartStyles && EditorUIController.updateChartStyles(this.props.storeChartSettings, this.props.storeFocusObjects); } _onDocumentContentReady() { @@ -304,8 +300,7 @@ class MainController extends Component { - - + {EditorUIController.getEditCommentControllers && EditorUIController.getEditCommentControllers()} ) diff --git a/apps/presentationeditor/mobile/src/view/Toolbar.jsx b/apps/presentationeditor/mobile/src/view/Toolbar.jsx index 8251fd2b0..a97919f9e 100644 --- a/apps/presentationeditor/mobile/src/view/Toolbar.jsx +++ b/apps/presentationeditor/mobile/src/view/Toolbar.jsx @@ -8,7 +8,7 @@ const ToolbarView = props => { {props.isShowBack && } - {props.isEdit && EditorUIController.getUndoRedo({ + {props.isEdit && EditorUIController.getUndoRedo && EditorUIController.getUndoRedo({ disabledUndo: !props.isCanUndo, disabledRedo: !props.isCanRedo, onUndoClick: props.onUndo, @@ -18,7 +18,7 @@ const ToolbarView = props => { {!Device.phone && {props.docTitle}} {props.openOptions('preview')}}> - {props.isEdit && EditorUIController.getToolbarOptions({ + {props.isEdit && EditorUIController.getToolbarOptions && EditorUIController.getToolbarOptions({ disabledAdd: props.disabledAdd || props.disabledControls, disabledEdit: props.disabledEdit || props.disabledControls, onEditClick: () => props.openOptions('edit'), From c7b2a9813d7ac39ffa7e4180e7f5534010342a8a Mon Sep 17 00:00:00 2001 From: SergeyEzhin Date: Mon, 19 Apr 2021 19:09:15 +0300 Subject: [PATCH 36/43] [PE mobile] Refactoring preview --- apps/presentationeditor/mobile/src/controller/Preview.jsx | 3 +-- apps/presentationeditor/mobile/src/page/main.jsx | 6 +----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/apps/presentationeditor/mobile/src/controller/Preview.jsx b/apps/presentationeditor/mobile/src/controller/Preview.jsx index b072f6638..df6cd83aa 100644 --- a/apps/presentationeditor/mobile/src/controller/Preview.jsx +++ b/apps/presentationeditor/mobile/src/controller/Preview.jsx @@ -92,8 +92,7 @@ const PreviewController = props => { // API Handlers const onEndDemonstration = () => { - if(props.previewVisible) - props.onClosePreview(); + props.onclosed(); }; return ( diff --git a/apps/presentationeditor/mobile/src/page/main.jsx b/apps/presentationeditor/mobile/src/page/main.jsx index 41ebdba85..4739278e2 100644 --- a/apps/presentationeditor/mobile/src/page/main.jsx +++ b/apps/presentationeditor/mobile/src/page/main.jsx @@ -70,7 +70,7 @@ class MainPage extends Component { return ( - {this.state.previewVisible ? : null} + {!this.state.previewVisible ? null : } {/* Top Navbar */} @@ -101,10 +101,6 @@ class MainPage extends Component { !this.state.collaborationVisible ? null : } - { - !this.state.previewVisible ? null : - - } From 3dd26e178b8a8a6b85613af230ce75822e42b1f3 Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Tue, 20 Apr 2021 12:47:57 +0300 Subject: [PATCH 37/43] [common] switch off version compare for debug --- apps/common/mobile/lib/view/About.jsx | 1 + apps/documenteditor/mobile/src/controller/Main.jsx | 2 +- vendor/framework7-react/build/webpack.config.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/common/mobile/lib/view/About.jsx b/apps/common/mobile/lib/view/About.jsx index cb6035fa7..a2fc8d61f 100644 --- a/apps/common/mobile/lib/view/About.jsx +++ b/apps/common/mobile/lib/view/About.jsx @@ -120,6 +120,7 @@ const PageAbout = props => { const About = inject("storeAppOptions")(observer(PageAbout)); About.appVersion = () => (__PRODUCT_VERSION__); +About.compareVersions = () => /d$/.test(__PRODUCT_VERSION__); export default About; \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/controller/Main.jsx b/apps/documenteditor/mobile/src/controller/Main.jsx index 061f1eae9..849e4760d 100644 --- a/apps/documenteditor/mobile/src/controller/Main.jsx +++ b/apps/documenteditor/mobile/src/controller/Main.jsx @@ -467,7 +467,7 @@ class MainController extends Component { if (this.changeServerVersion) return true; const _t = this._t; - if (About.appVersion() !== buildVersion && !window.compareVersions) { + if (About.appVersion() !== buildVersion && !About.compareVersions()) { this.changeServerVersion = true; f7.dialog.alert( _t.errorServerVersion, diff --git a/vendor/framework7-react/build/webpack.config.js b/vendor/framework7-react/build/webpack.config.js index 10daaf441..d0ca26d72 100644 --- a/vendor/framework7-react/build/webpack.config.js +++ b/vendor/framework7-react/build/webpack.config.js @@ -160,7 +160,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 : '6.2.0'), + __PRODUCT_VERSION__: JSON.stringify(process.env.PRODUCT_VERSION ? process.env.PRODUCT_VERSION : '6.2.0d'), __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'), From 57043e6602f1b01ad9ab77d34be3019bf98cd5a5 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Tue, 20 Apr 2021 19:49:49 +0300 Subject: [PATCH 38/43] [DE mobile] Changes related to main controller --- apps/documenteditor/mobile/locale/en.json | 3 +- .../mobile/src/controller/Error.jsx | 7 ++--- .../mobile/src/controller/LongActions.jsx | 4 +-- .../mobile/src/controller/Main.jsx | 29 +++++++++++++++++-- .../src/controller/settings/Download.jsx | 10 +++++-- 5 files changed, 41 insertions(+), 12 deletions(-) diff --git a/apps/documenteditor/mobile/locale/en.json b/apps/documenteditor/mobile/locale/en.json index 9ca0208b9..7e4fee34d 100644 --- a/apps/documenteditor/mobile/locale/en.json +++ b/apps/documenteditor/mobile/locale/en.json @@ -94,7 +94,8 @@ "errorUpdateVersionOnDisconnect": "Internet connection has been restored, and the file version has been changed.
Before you can continue working, you need to download the file or copy its content to make sure nothing is lost, and then reload this page.", "errorDefaultMessage": "Error code: %1", "criticalErrorExtText": "Press 'OK' to back to document list.", - "notcriticalErrorTitle": "Warning" + "notcriticalErrorTitle": "Warning", + "scriptLoadError": "The connection is too slow, some of the components could not be loaded. Please reload the page." }, "LongActions": { "openTitleText": "Opening Document", diff --git a/apps/documenteditor/mobile/src/controller/Error.jsx b/apps/documenteditor/mobile/src/controller/Error.jsx index 6ae81ef0d..ff499f251 100644 --- a/apps/documenteditor/mobile/src/controller/Error.jsx +++ b/apps/documenteditor/mobile/src/controller/Error.jsx @@ -1,8 +1,7 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect } from 'react'; import { inject } from 'mobx-react'; import { f7 } from 'framework7-react'; import { useTranslation } from 'react-i18next'; -import LongActionsController from "./LongActions"; const ErrorController = inject('storeAppOptions')(({storeAppOptions, LoadingDocument}) => { const {t} = useTranslation(); @@ -22,7 +21,7 @@ const ErrorController = inject('storeAppOptions')(({storeAppOptions, LoadingDocu if (id === Asc.c_oAscError.ID.LoadingScriptError) { f7.notification.create({ title: _t.criticalErrorTitle, - text: _t.criticalErrorTitle, + text: _t.scriptLoadError, closeButton: true }).open(); return; @@ -183,7 +182,7 @@ const ErrorController = inject('storeAppOptions')(({storeAppOptions, LoadingDocu // report only critical errors Common.Gateway.reportError(id, config.msg); - config.title = this.criticalErrorTitle; + config.title = _t.criticalErrorTitle; if (storeAppOptions.canBackToFolder && !storeAppOptions.isDesktopApp) { config.msg += '

' + _t.criticalErrorExtText; diff --git a/apps/documenteditor/mobile/src/controller/LongActions.jsx b/apps/documenteditor/mobile/src/controller/LongActions.jsx index 2c2e0f9fb..5365f7264 100644 --- a/apps/documenteditor/mobile/src/controller/LongActions.jsx +++ b/apps/documenteditor/mobile/src/controller/LongActions.jsx @@ -20,7 +20,7 @@ class LongActions extends Component { } closePreloader() { - if (this.loadMask.el) { + if (this.loadMask && this.loadMask.el) { f7.dialog.close(this.loadMask.el); } } @@ -70,7 +70,7 @@ class LongActions extends Component { if (action) { this.setLongActionView(action) } else { - this.loadMask.el && this.loadMask.el.classList.contains('modal-in') && f7.dialog.close(this.loadMask.el); + this.loadMask && this.loadMask.el && this.loadMask.el.classList.contains('modal-in') && f7.dialog.close(this.loadMask.el); } } diff --git a/apps/documenteditor/mobile/src/controller/Main.jsx b/apps/documenteditor/mobile/src/controller/Main.jsx index 061f1eae9..45e56bb10 100644 --- a/apps/documenteditor/mobile/src/controller/Main.jsx +++ b/apps/documenteditor/mobile/src/controller/Main.jsx @@ -189,6 +189,9 @@ class MainController extends Component { }; const onDocumentContentReady = () => { + if (this._isDocReady) + return; + const appOptions = this.props.storeAppOptions; const appSettings = this.props.storeApplicationSettings; @@ -327,8 +330,8 @@ class MainController extends Component { 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)); - //me.api.asc_registerCallback('asc_onDocumentModifiedChanged', _.bind(me.onDocumentModifiedChanged, me)); - //me.api.asc_registerCallback('asc_onDocumentCanSaveChanged', _.bind(me.onDocumentCanSaveChanged, me)); + this.api.asc_registerCallback('asc_onDocumentModifiedChanged', this.onDocumentModifiedChanged.bind(this)); + this.api.asc_registerCallback('asc_onDocumentCanSaveChanged', this.onDocumentCanSaveChanged.bind(this)); //if (me.stackLongActions.exist({id: ApplyEditRights, type: Asc.c_oAscAsyncActionType['BlockInteraction']})) { // me.onLongActionEnd(Asc.c_oAscAsyncActionType['BlockInteraction'], ApplyEditRights); @@ -342,6 +345,19 @@ class MainController extends Component { window.onunload = this.onUnload.bind(this); } + onDocumentModifiedChanged () { + const isModified = this.api.asc_isDocumentCanSave(); + if (this._state.isDocModified !== isModified) { + this._isDocReady && Common.Gateway.setDocumentModified(this.api.isDocumentModified()); + } + + this.updateWindowTitle(); + } + + onDocumentCanSaveChanged (isCanSave) { + // + } + onBeforeUnload () { LocalStorage.save(); @@ -485,6 +501,7 @@ class MainController extends Component { this.api.asc_registerCallback('asc_onServerVersion', this.onServerVersion.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)); EditorUIController.initThemeColors && EditorUIController.initThemeColors(); @@ -677,6 +694,14 @@ class MainController extends Component { } } + 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); diff --git a/apps/documenteditor/mobile/src/controller/settings/Download.jsx b/apps/documenteditor/mobile/src/controller/settings/Download.jsx index 5bf78d0ba..187b65c7b 100644 --- a/apps/documenteditor/mobile/src/controller/settings/Download.jsx +++ b/apps/documenteditor/mobile/src/controller/settings/Download.jsx @@ -55,6 +55,8 @@ class DownloadController extends Component { const DownloadWithTranslation = withTranslation()(DownloadController); const onAdvancedOptions = (type, advOptions, mode, formatOptions, _t, canRequestClose) => { + if ($$('.dlg-adv-options.modal-in').length > 0) return; + const api = Common.EditorApi.get(); if (type == Asc.c_oAscAdvancedOptionsID.TXT) { let picker; @@ -97,7 +99,8 @@ const onAdvancedOptions = (type, advOptions, mode, formatOptions, _t, canRequest '
' + '
' + '
', - buttons: buttons + buttons: buttons, + cssClass: 'dlg-adv-options' }).open(); dialog.on('opened', () => { picker = f7.picker.create({ @@ -122,7 +125,7 @@ const onAdvancedOptions = (type, advOptions, mode, formatOptions, _t, canRequest const password = document.getElementById('modal-password').value; api.asc_setAdvancedOptions(type, new Asc.asc_CDRMAdvancedOptions(password)); //if (!me._isDocReady) { - //me.onLongActionBegin(Asc.c_oAscAsyncActionType['BlockInteraction'], LoadingDocument); + //Common.Notifications.trigger('preloader:beginAction', Asc.c_oAscAsyncActionType['BlockInteraction'], this.LoadingDocument); //} } }]; @@ -138,7 +141,8 @@ const onAdvancedOptions = (type, advOptions, mode, formatOptions, _t, canRequest text: _t.txtProtected, content: '
', - buttons: buttons + buttons: buttons, + cssClass: 'dlg-adv-options' }).open(); } }; From eb63c42891f64ccc5452050da85214d34a280627 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Tue, 20 Apr 2021 19:52:36 +0300 Subject: [PATCH 39/43] [PE mobile] Make main controller, add error controller, add controller for long actions --- apps/presentationeditor/mobile/locale/en.json | 103 +++- .../mobile/src/controller/Error.jsx | 222 +++++++ .../mobile/src/controller/LongActions.jsx | 192 ++++++ .../mobile/src/controller/Main.jsx | 559 ++++++++++++++++-- .../settings/ApplicationSettings.jsx | 17 +- .../mobile/src/page/app.jsx | 2 + 6 files changed, 1043 insertions(+), 52 deletions(-) create mode 100644 apps/presentationeditor/mobile/src/controller/Error.jsx create mode 100644 apps/presentationeditor/mobile/src/controller/LongActions.jsx diff --git a/apps/presentationeditor/mobile/locale/en.json b/apps/presentationeditor/mobile/locale/en.json index bcf17b851..a4aaae940 100644 --- a/apps/presentationeditor/mobile/locale/en.json +++ b/apps/presentationeditor/mobile/locale/en.json @@ -21,9 +21,110 @@ "Slide subtitle": "Slide subtitle", "Table": "Table", "Slide title": "Slide title" - } + }, + "closeButtonText": "Close File", + "advDRMOptions": "Protected File", + "advDRMPassword": "Password", + + "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", + + "errorProcessSaveResult": "Saving is failed.", + "criticalErrorTitle": "Error", + "warnProcessRightsChange": "You have been denied the right to edit the file.", + "errorAccessDeny": "You are trying to perform an action you do not have rights for.
Please contact your Document Server administrator.", + + "errorUpdateVersion": "The file version has been changed. The page will be reloaded.", + "titleUpdateVersion": "Version changed", + "textHasMacros": "The file contains automatic macros.
Do you want to run macros?", + "textRemember": "Remember my choice", + "textYes": "Yes", + "textNo": "No" } }, + "Error": { + "criticalErrorTitle": "Error", + "unknownErrorText": "Unknown error.", + "convertationTimeoutText": "Convertation timeout exceeded.", + "openErrorText": "An error has occurred while opening the file", + "saveErrorText": "An error has occurred while saving the file", + "downloadErrorText": "Download failed.", + "uploadImageSizeMessage": "Maximium image size limit exceeded.", + "uploadImageExtMessage": "Unknown image format.", + "uploadImageFileCountMessage": "No images uploaded.", + "splitMaxRowsErrorText": "The number of rows must be less than %1", + "splitMaxColsErrorText": "The number of columns must be less than %1", + "splitDividerErrorText": "The number of rows must be a divisor of %1", + "errorKeyEncrypt": "Unknown key descriptor", + "errorKeyExpire": "Key descriptor expired", + "errorUsersExceed": "Count of users was exceed", + "errorViewerDisconnect": "Connection is lost. You can still view the document,
but will not be able to download until the connection is restored and page is reloaded.", + "errorFilePassProtect": "The file is password protected and could not be opened.", + "errorStockChart": "Incorrect row order. To build a stock chart place the data on the sheet in the following order:
opening price, max price, min price, closing price.", + "errorDataRange": "Incorrect data range.", + "errorDatabaseConnection": "External error.
Database connection error. Please, contact support.", + "errorUserDrop": "The file cannot be accessed right now.", + "errorConnectToServer": " The document could not be saved. Please check connection settings or contact your administrator.
When you click the 'OK' button, you will be prompted to download the document.", + "errorBadImageUrl": "Image url is incorrect", + "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.", + "errorDataEncrypted": "Encrypted changes have been received, they cannot be deciphered.", + "errorAccessDeny": "You are trying to perform an action you do not have rights for.
Please contact your Document Server administrator.", + "errorEditingDownloadas": "An error occurred during the work with the document.
Use the 'Download' option to save the file backup copy to your computer hard drive.", + "errorFileSizeExceed": "The file size exceeds the limitation set for your server.
Please contact your Document Server administrator for details.", + "errorUpdateVersionOnDisconnect": "Internet connection has been restored, and the file version has been changed.
Before you can continue working, you need to download the file or copy its content to make sure nothing is lost, and then reload this page.", + "errorDefaultMessage": "Error code: %1", + "criticalErrorExtText": "Press 'OK' to back to document list.", + "notcriticalErrorTitle": "Warning", + "scriptLoadError": "The connection is too slow, some of the components could not be loaded. Please reload the page." + }, + "LongActions": { + "openTitleText": "Opening Document", + "openTextText": "Opening document...", + "saveTitleText": "Saving Document", + "saveTextText": "Saving document...", + "loadFontsTitleText": "Loading Data", + "loadFontsTextText": "Loading data...", + "loadImagesTitleText": "Loading Images", + "loadImagesTextText": "Loading images...", + "loadFontTitleText": "Loading Data", + "loadFontTextText": "Loading data...", + "loadImageTitleText": "Loading Image", + "loadImageTextText": "Loading image...", + "downloadTitleText": "Downloading Document", + "downloadTextText": "Downloading document...", + "printTitleText": "Printing Document", + "printTextText": "Printing document...", + "uploadImageTitleText": "Uploading Image", + "uploadImageTextText": "Uploading image...", + "applyChangesTitleText": "Loading Data", + "applyChangesTextText": "Loading data...", + "savePreparingText": "Preparing to save", + "savePreparingTitle": "Preparing to save. Please wait...", + "waitText": "Please, wait...", + "txtEditingMode": "Set editing mode...", + "loadingDocumentTitleText": "Loading document", + "loadingDocumentTextText": "Loading document...", + "textLoadingDocument": "Loading document" + }, "ContextMenu": { "menuViewComment": "View Comment", "menuAddComment": "Add Comment", diff --git a/apps/presentationeditor/mobile/src/controller/Error.jsx b/apps/presentationeditor/mobile/src/controller/Error.jsx new file mode 100644 index 000000000..a8cd9213e --- /dev/null +++ b/apps/presentationeditor/mobile/src/controller/Error.jsx @@ -0,0 +1,222 @@ +import React, { useEffect } from 'react'; +import { inject } from 'mobx-react'; +import { f7 } from 'framework7-react'; +import { useTranslation } from 'react-i18next'; + +const ErrorController = inject('storeAppOptions')(({storeAppOptions, LoadingDocument}) => { + const {t} = useTranslation(); + const _t = t("Error", { returnObjects: true }); + + useEffect(() => { + Common.Notifications.on('engineCreated', (api) => { + api.asc_registerCallback('asc_onError', onError); + }); + return () => { + const api = Common.EditorApi.get(); + api.asc_unregisterCallback('asc_onError', onError); + } + }); + + const onError = (id, level, errData) => { + if (id === -82) return; // format error + + 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); + + 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.errorKeyEncrypt; + break; + + case Asc.c_oAscError.ID.KeyExpire: + config.msg = _t.errorKeyExpire; + 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.DataRangeError: + config.msg = _t.errorDataRange; + 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.EditingError: + config.msg = _t.errorEditingDownloadas; + break; + + case Asc.c_oAscError.ID.ConvertationOpenLimitError: + config.msg = _t.errorFileSizeExceed; + break; + + case Asc.c_oAscError.ID.UpdateVersion: + config.msg = _t.errorUpdateVersionOnDisconnect; + 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 += '

' + _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: 'OK', + onClick: config.callback + } + ] + }).open(); + + Common.component.Analytics.trackEvent('Internal Error', id.toString()); + }; + + return null +}); + +export default ErrorController; \ No newline at end of file diff --git a/apps/presentationeditor/mobile/src/controller/LongActions.jsx b/apps/presentationeditor/mobile/src/controller/LongActions.jsx new file mode 100644 index 000000000..0828925ab --- /dev/null +++ b/apps/presentationeditor/mobile/src/controller/LongActions.jsx @@ -0,0 +1,192 @@ +import React, { Component } from 'react'; +import { inject } from 'mobx-react'; +import { f7 } from 'framework7-react'; +import { withTranslation } from 'react-i18next'; +import IrregularStack from "../../../../common/mobile/utils/IrregularStack"; + +class LongActions extends Component { + constructor(props) { + super(props); + + this.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;} + }); + + this.onLongActionBegin = this.onLongActionBegin.bind(this); + this.onLongActionEnd = this.onLongActionEnd.bind(this); + this.onOpenDocument = this.onOpenDocument.bind(this); + this.closePreloader = this.closePreloader.bind(this); + } + + closePreloader() { + if (this.loadMask && this.loadMask.el) { + f7.dialog.close(this.loadMask.el); + } + } + + componentDidMount() { + Common.Notifications.on('engineCreated', (api) => { + api.asc_registerCallback('asc_onStartAction', this.onLongActionBegin); + api.asc_registerCallback('asc_onEndAction', this.onLongActionEnd); + api.asc_registerCallback('asc_onOpenDocumentProgress', this.onOpenDocument); + }); + Common.Notifications.on('preloader:endAction', this.onLongActionEnd); + Common.Notifications.on('preloader:beginAction', this.onLongActionBegin); + Common.Notifications.on('preloader:close', this.closePreloader); + } + + componentWillUnmount() { + const api = Common.EditorApi.get(); + api.asc_unregisterCallback('asc_onStartAction', this.onLongActionBegin); + api.asc_unregisterCallback('asc_onEndAction', this.onLongActionEnd); + api.asc_unregisterCallback('asc_onOpenDocumentProgress', this.onOpenDocument); + + Common.Notifications.off('preloader:endAction', this.onLongActionEnd); + Common.Notifications.off('preloader:beginAction', this.onLongActionBegin); + Common.Notifications.off('preloader:close', this.closePreloader); + } + + onLongActionBegin (type, id) { + const action = {id: id, type: type}; + this.stackLongActions.push(action); + this.setLongActionView(action); + } + + onLongActionEnd (type, id) { + let action = {id: id, type: type}; + this.stackLongActions.pop(action); + + //this.updateWindowTitle(true); + + action = this.stackLongActions.get({type: Asc.c_oAscAsyncActionType.Information}); + + if (action) { + this.setLongActionView(action) + } + + action = this.stackLongActions.get({type: Asc.c_oAscAsyncActionType.BlockInteraction}); + + if (action) { + this.setLongActionView(action) + } else { + this.loadMask && this.loadMask.el && this.loadMask.el.classList.contains('modal-in') && f7.dialog.close(this.loadMask.el); + } + } + + setLongActionView (action) { + const { t } = this.props; + const _t = t("LongActions", { returnObjects: true }); + let title = ''; + let text = ''; + switch (action.id) { + case Asc.c_oAscAsyncAction['Open']: + title = _t.openTitleText; + text = _t.openTextText; + break; + + case Asc.c_oAscAsyncAction['Save']: + title = _t.saveTitleText; + text = _t.saveTextText; + break; + + case Asc.c_oAscAsyncAction['LoadDocumentFonts']: + 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']) { + return; + } + + if (this.loadMask && this.loadMask.el && this.loadMask.el.classList.contains('modal-in')) { + this.loadMask.el.getElementsByClassName('dialog-title')[0].innerHTML = title; + } else { + this.loadMask = f7.dialog.preloader(title); + } + } + + } + + onOpenDocument (progress) { + if (this.loadMask && this.loadMask.el) { + const $title = this.loadMask.el.getElementsByClassName('dialog-title')[0]; + const proc = (progress.asc_getCurrentFont() + progress.asc_getCurrentImage())/(progress.asc_getFontsCount() + progress.asc_getImagesCount()); + + const { t } = this.props; + const _t = t("LongActions", { returnObjects: true }); + $title.innerHTML = `${_t.textLoadingDocument}: ${Math.min(Math.round(proc * 100), 100)}%`; + } + } + + render() { + return null; + } +} + +const LongActionsController = withTranslation()(LongActions); + +export default LongActionsController; \ No newline at end of file diff --git a/apps/presentationeditor/mobile/src/controller/Main.jsx b/apps/presentationeditor/mobile/src/controller/Main.jsx index 8c5e89e0b..aa626e48e 100644 --- a/apps/presentationeditor/mobile/src/controller/Main.jsx +++ b/apps/presentationeditor/mobile/src/controller/Main.jsx @@ -7,19 +7,44 @@ import CollaborationController from '../../../../common/mobile/lib/controller/co import EditorUIController from '../lib/patch'; import { CommentsController, - AddCommentController, - EditCommentController, ViewCommentsController } from "../../../../common/mobile/lib/controller/collaboration/Comments"; +import ErrorController from "./Error"; +import LongActionsController from "./LongActions"; +import {LocalStorage} from "../../../../common/mobile/utils/LocalStorage"; +import About from '../../../../common/mobile/lib/view/About'; -@inject("storeFocusObjects", "storeAppOptions", "storePresentationInfo", "storePresentationSettings", "storeSlideSettings", "storeTextSettings", "storeTableSettings", "storeChartSettings", "storeLinkSettings") +@inject( + "storeFocusObjects", + "storeAppOptions", + "storePresentationInfo", + "storePresentationSettings", + "storeSlideSettings", + "storeTextSettings", + "storeTableSettings", + "storeChartSettings", + "storeLinkSettings", + "storeApplicationSettings" + ) class MainController extends Component { - constructor(props) { + constructor (props) { super(props) window.editorType = 'pe'; + + this.LoadingDocument = -256; + + this._state = { + licenseType: false, + isDocModified: false + }; + + this.defaultTitleText = __APP_TITLE_TEXT__; + + const { t } = this.props; + this._t = t('Controller.Main', {returnObjects:true}); } - initSdk() { + initSdk () { const script = document.createElement("script"); script.src = "../../../../sdkjs/develop/sdkjs/slide/scripts.js"; script.async = true; @@ -54,7 +79,15 @@ class MainController extends Component { this.props.storeAppOptions.setConfigOptions(this.editorConfig); this.editorConfig.lang && this.api.asc_setLocale(this.editorConfig.lang); - // console.log(this.editorConfig); + + let value = LocalStorage.getItem("pe-mobile-macros-mode"); + if (value === null) { + value = this.editorConfig.customization ? this.editorConfig.customization.macrosMode : 'warn'; + value = (value === 'enable') ? 1 : (value === 'disable' ? 2 : 0); + } else { + value = parseInt(value); + } + this.props.storeApplicationSettings.changeMacrosSettings(value); }; const loadDocument = data => { @@ -85,15 +118,15 @@ class MainController extends Component { docInfo.put_Permissions(_permissions); docInfo.put_EncryptedInfo(this.editorConfig.encryptionKeys); - // var enable = !this.editorConfig.customization || (this.editorConfig.customization.macros!==false); - // docInfo.asc_putIsEnabledMacroses(!!enable); - // enable = !this.editorConfig.customization || (this.editorConfig.customization.plugins!==false); - // docInfo.asc_putIsEnabledPlugins(!!enable); + let enable = !this.editorConfig.customization || (this.editorConfig.customization.macros !== false); + docInfo.asc_putIsEnabledMacroses(!!enable); + enable = !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', _.bind(this.onLicenseChanged, this)); - // this.api.asc_registerCallback('asc_onRunAutostartMacroses', _.bind(this.onRunAutostartMacroses, this)); + this.api.asc_registerCallback('asc_onLicenseChanged', this.onLicenseChanged.bind(this)); + this.api.asc_registerCallback('asc_onRunAutostartMacroses', this.onRunAutostartMacroses.bind(this)); this.api.asc_setDocInfo(docInfo); this.api.asc_getEditorPermissions(this.editorConfig.licenseUrl, this.editorConfig.customerId); @@ -111,16 +144,16 @@ class MainController extends Component { }; const onEditorPermissions = params => { - let me = this; const licType = params.asc_getLicenseType(); - me.appOptions.canLicense = (licType === Asc.c_oLicenseResult.Success || licType === Asc.c_oLicenseResult.SuccessLimit); + this.appOptions.canLicense = (licType === Asc.c_oLicenseResult.Success || licType === Asc.c_oLicenseResult.SuccessLimit); - this.props.storeAppOptions.setPermissionOptions(this.document, licType, params, this.permissions); + const storeAppOptions = this.props.storeAppOptions; + storeAppOptions.setPermissionOptions(this.document, licType, params, this.permissions); + this.applyMode(storeAppOptions); - // me.api.asc_setViewMode(!me.appOptions.isEdit); - me.api.asc_setViewMode(false); - me.api.asc_LoadDocument(); + this.api.asc_LoadDocument(); + this.api.Resize(); }; const _process_array = (array, fn) => { @@ -144,24 +177,36 @@ class MainController extends Component { 'translate': t('Controller.Main.SDK', {returnObjects:true}) }); + Common.Notifications.trigger('engineCreated', this.api); Common.EditorApi = {get: () => this.api}; this.appOptions = {}; this.bindEvents(); - let value = null /*Common.localStorage.getItem("pe-settings-fontrender")*/; + let value = LocalStorage.getItem("pe-settings-fontrender"); if (value===null) value = window.devicePixelRatio > 1 ? '1' : '3'; this.api.SetFontRenderingMode(parseInt(value)); this.api.SetDrawingFreeze(true); this.api.SetThemesPath("../../../../sdkjs/slide/themes/"); - // Common.Utils.Metric.setCurrentMetric(1); //pt + Common.Utils.Metric.setCurrentMetric(1); //pt Common.Gateway.on('init', loadConfig); - // Common.Gateway.on('showmessage', _.bind(me.onExternalMessage, me)); + Common.Gateway.on('showmessage', this.onExternalMessage.bind(this)); Common.Gateway.on('opendocument', loadDocument); Common.Gateway.appReady(); - Common.Notifications.trigger('engineCreated', this.api); + 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); }); @@ -174,11 +219,76 @@ class MainController extends Component { document.body.appendChild(script); } - bindEvents() { - - // me.api.asc_registerCallback('asc_onError', _.bind(me.onError, me)); - this.api.asc_registerCallback('asc_onDocumentContentReady', this._onDocumentContentReady.bind(this)); - this.api.asc_registerCallback('asc_onOpenDocumentProgress', this._onOpenDocumentProgress.bind(this)); + 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('pe-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)); + + this.api.asc_registerCallback('asc_onDocumentModifiedChanged', this.onDocumentModifiedChanged.bind(this)); + this.api.asc_registerCallback('asc_onDocumentCanSaveChanged', this.onDocumentCanSaveChanged.bind(this)); + + //if (me.stackLongActions.exist({id: ApplyEditRights, type: Asc.c_oAscAsyncActionType['BlockInteraction']})) { + // me.onLongActionEnd(Asc.c_oAscAsyncActionType['BlockInteraction'], ApplyEditRights); + //} else if (!this._isDocReady) { + // me.hidePreloader(); + // me.onLongActionBegin(Asc.c_oAscAsyncActionType['BlockInteraction'], LoadingDocument); + //} + + // Message on window close + window.onbeforeunload = this.onBeforeUnload.bind(this); + window.onunload = this.onUnload.bind(this); + } + + onDocumentModifiedChanged () { + const isModified = this.api.asc_isDocumentCanSave(); + if (this._state.isDocModified !== isModified) { + this._isDocReady && Common.Gateway.setDocumentModified(this.api.isDocumentModified()); + } + + this.updateWindowTitle(); + } + + onDocumentCanSaveChanged (isCanSave) { + // + } + + onBeforeUnload () { + LocalStorage.save(); + + if (this.api.isDocumentModified()) { + this.api.asc_stopSaving(); + this.continueSavingTimer = window.setTimeout(() => { + this.api.asc_continueSaving(); + }, 500); + + return this._t.leavePageText; + } + } + + onUnload () { + if (this.continueSavingTimer) + clearTimeout(this.continueSavingTimer); + } + + bindEvents () { + 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)); EditorUIController.initThemeColors && EditorUIController.initThemeColors(); @@ -266,12 +376,48 @@ class MainController extends Component { EditorUIController.updateChartStyles && EditorUIController.updateChartStyles(this.props.storeChartSettings, this.props.storeFocusObjects); } - _onDocumentContentReady() { + 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); + + let value = LocalStorage.getItem("pe-settings-zoom"); + const zf = (value!==null) ? parseInt(value) : (appOptions.customization && appOptions.customization.zoom ? parseInt(appOptions.customization.zoom) : -1); + (zf === -1) ? this.api.zoomFitToPage() : ((zf === -2) ? this.api.zoomFitToWidth() : this.api.zoom(zf>0 ? zf : 100)); + + value = LocalStorage.getBool("pe-mobile-spellcheck", !(appOptions.customization && appOptions.customization.spellcheck===false)); + appSettings.changeSpellCheck(value); + this.api.asc_setSpellCheck(value); + + this.updateWindowTitle(true); + + this.api.SetTextBoxInputMode(LocalStorage.getBool("pe-settings-inputmode")); + + if (appOptions.isEdit && this.needToUpdateVersion) { + Common.Notifications.trigger('api:disconnect'); + } + + Common.Gateway.on('processsaveresult', this.onProcessSaveResult.bind(this)); + 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(); - // me.api.asc_GetDefaultTableStyles && _.defer(function () {me.api.asc_GetDefaultTableStyles()}); + this.api.asc_GetDefaultTableStyles && setTimeout(() => {this.api.asc_GetDefaultTableStyles()}, 1); this.applyLicense(); @@ -281,23 +427,354 @@ class MainController extends Component { Common.Notifications.trigger('document:ready'); } - _onOpenDocumentProgress(progress) { - // if (this.loadMask) { - // var $title = $$(this.loadMask).find('.modal-title'), - // const proc = (progress.asc_getCurrentFont() + progress.asc_getCurrentImage())/(progress.asc_getFontsCount() + progress.asc_getImagesCount()); - - // $title.text(this.textLoadingDocument + ': ' + Math.min(Math.round(proc * 100), 100) + '%'); - // } + 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() { - /* TO DO */ - Common.Notifications.trigger('toolbar:activatecontrols'); + applyLicense () { + const _t = this._t; + 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("pe-opensource-warning"); + value = (value !== null) ? parseInt(value) : 0; + const now = (new Date).getTime(); + if (now - value > 86400000) { + LocalStorage.setItem("pe-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) ? 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'); + Common.Notifications.trigger('toolbar:deactivateeditcontrols'); + Common.Notifications.trigger('api:disconnect'); + } + + let value = LocalStorage.getItem("pe-license-warning"); + value = (value !== null) ? parseInt(value) : 0; + const now = (new Date).getTime(); + + if (now - value > 86400000) { + LocalStorage.setItem("pe-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'); + } } - render() { + onUpdateVersion (callback) { + const _t = this._t; + + 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._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; + } + + onAdvancedOptions (type, advOptions) { + if ($$('.dlg-adv-options.modal-in').length > 0) return; + + const _t = this._t; + + if (type == Asc.c_oAscAdvancedOptionsID.DRM) { + Common.Notifications.trigger('preloader:close'); + Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], this.LoadingDocument); + + const buttons = [{ + text: 'OK', + bold: true, + close: false, + 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.props.storeAppOptions.canRequestClose) + buttons.push({ + text: _t.closeButtonText, + onClick: () => { + Common.Gateway.requestClose(); + } + }); + + f7.dialog.create({ + title: _t.advDRMOptions, + text: (typeof advOptions === 'string' ? advOptions : _t.txtProtected), + content: + `
+ +
`, + buttons: buttons, + cssClass: 'dlg-adv-options' + }).open(); + } + } + + 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'); + } + } + + onRunAutostartMacroses () { + const config = this.props.storeAppOptions.config; + const enable = !config.customization || (config.customization.macros !== false); + if (enable) { + const value = this.props.storeApplicationSettings.macrosMode; + if (value === 1) { + this.api.asc_runAutostartMacroses(); + } else if (value === 0) { + const _t = this._t; + f7.dialog.create({ + title: _t.notcriticalErrorTitle, + text: _t.textHasMacros, + content: `
+ + ${_t.textRemember} +
`, + buttons: [{ + text: _t.textYes, + onClick: () => { + const dontshow = $$('input[name="checkbox-show-macros"]').prop('checked'); + if (dontshow) { + this.props.storeApplicationSettings.changeMacrosSettings(1); + LocalStorage.setItem("pe-mobile-macros-mode", 1); + } + setTimeout(() => { + this.api.asc_runAutostartMacroses(); + }, 1); + }}, + { + text: _t.textNo, + onClick: () => { + const dontshow = $$('input[name="checkbox-show-macros"]').prop('checked'); + if (dontshow) { + this.props.storeApplicationSettings.changeMacrosSettings(2); + LocalStorage.setItem("pe-mobile-macros-mode", 2); + } + } + }] + }).open(); + } + } + } + + onProcessSaveResult (data) { + this.api.asc_OnSaveEnd(data.result); + + if (data && data.result === false) { + const _t = this._t; + f7.dialog.alert( + (!data.message) ? _t.errorProcessSaveResult : data.message, + _t.criticalErrorTitle + ); + } + } + + 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._t; + f7.dialog.alert( + (!data.message) ? _t.warnProcessRightsChange : data.message, + _t.notcriticalErrorTitle, + () => { appOptions.changeEditingRights(false); } + ); + } + } + } + + onDownloadAs () { + if ( !this.props.storeAppOptions.canDownload) { + Common.Gateway.reportError(Asc.c_oAscError.ID.AccessDeny, this.errorAccessDeny); + return; + } + this._state.isFromGatewayDownloadAs = true; + this.api.asc_DownloadAs(new Asc.asc_CDownloadOptions(Asc.c_oAscFileType.PPTX, true)); + } + + onRequestClose () { + Common.Gateway.requestClose(); + } + + render () { return ( + + {EditorUIController.getEditCommentControllers && EditorUIController.getEditCommentControllers()} @@ -306,7 +783,7 @@ class MainController extends Component { ) } - componentDidMount() { + componentDidMount () { this.initSdk(); } } diff --git a/apps/presentationeditor/mobile/src/controller/settings/ApplicationSettings.jsx b/apps/presentationeditor/mobile/src/controller/settings/ApplicationSettings.jsx index c976d1f66..bc72b63bb 100644 --- a/apps/presentationeditor/mobile/src/controller/settings/ApplicationSettings.jsx +++ b/apps/presentationeditor/mobile/src/controller/settings/ApplicationSettings.jsx @@ -1,5 +1,6 @@ import React, { Component } from "react"; import { ApplicationSettings } from "../../view/settings/ApplicationSettings"; +import { LocalStorage } from '../../../../../common/mobile/utils/LocalStorage'; class ApplicationSettingsController extends Component { constructor(props) { @@ -8,23 +9,19 @@ class ApplicationSettingsController extends Component { setUnitMeasurement(value) { const api = Common.EditorApi.get(); - value = (value!==null) ? parseInt(value) : Common.Utils.Metric.getDefaultMetric(); + value = (value !== null) ? parseInt(value) : Common.Utils.Metric.getDefaultMetric(); Common.Utils.Metric.setCurrentMetric(value); - // Common.localStorage.setItem("pe-mobile-settings-unit", value); - 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)); + LocalStorage.setItem("pe-mobile-settings-unit", value); + 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)); } switchSpellCheck(value) { - const api = Common.EditorApi.get(); - // let state = value === '1' ? true : false; - // Common.localStorage.setItem("pe-mobile-spellcheck", state ? 1 : 0); - // Common.Utils.InternalSettings.set("pe-mobile-spellcheck", state); - api.asc_setSpellCheck(value); + LocalStorage.setBool("pe-mobile-spellcheck", value); + Common.EditorApi.get().asc_setSpellCheck(value); } setMacrosSettings(value) { - Common.Utils.InternalSettings.set("pe-mobile-macros-mode", value); - // Common.localStorage.setItem("pe-mobile-macros-mode", value); + LocalStorage.setItem("pe-mobile-macros-mode", value); } diff --git a/apps/presentationeditor/mobile/src/page/app.jsx b/apps/presentationeditor/mobile/src/page/app.jsx index 8e4ceafe1..55d94d9b2 100644 --- a/apps/presentationeditor/mobile/src/page/app.jsx +++ b/apps/presentationeditor/mobile/src/page/app.jsx @@ -3,6 +3,8 @@ 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'; From 7c72e8cb1b3e06ac72b0e7156d33b8a8d3206dc4 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Wed, 21 Apr 2021 16:32:30 +0300 Subject: [PATCH 40/43] [SSE mobile] Changes for code decomposition --- .../mobile/src/controller/Main.jsx | 52 ++----- .../mobile/src/store/focusObjects.js | 129 +----------------- 2 files changed, 12 insertions(+), 169 deletions(-) diff --git a/apps/spreadsheeteditor/mobile/src/controller/Main.jsx b/apps/spreadsheeteditor/mobile/src/controller/Main.jsx index 1e166bd36..afd6c2524 100644 --- a/apps/spreadsheeteditor/mobile/src/controller/Main.jsx +++ b/apps/spreadsheeteditor/mobile/src/controller/Main.jsx @@ -187,6 +187,8 @@ class MainController extends Component { // 'translate': translate }); + Common.EditorApi = {get: () => this.api}; + this.appOptions = {}; this.bindEvents(); @@ -202,7 +204,6 @@ class MainController extends Component { Common.Gateway.appReady(); Common.Notifications.trigger('engineCreated', this.api); - Common.EditorApi = {get: () => this.api}; }, error => { console.log('promise failed ' + error); }); @@ -227,58 +228,21 @@ class MainController extends Component { // me.api.asc_registerCallback('asc_onDocumentName', _.bind(me.onDocumentName, me)); me.api.asc_registerCallback('asc_onEndAction', me._onLongActionEnd.bind(me)); - const storeSpreadsheetSettings = this.props.storeSpreadsheetSettings; - const storeFocusObjects = this.props.storeFocusObjects; - const storeCellSettings = this.props.storeCellSettings; - const storeTextSettings = this.props.storeTextSettings; - const storeChartSettings = this.props.storeChartSettings; - const styleSize = storeCellSettings.styleSize; - - this.api.asc_registerCallback('asc_onSelectionChanged', cellInfo => { - console.log(cellInfo); - - storeFocusObjects.resetCellInfo(cellInfo); - storeCellSettings.initCellSettings(cellInfo); - storeTextSettings.initTextSettings(cellInfo); + EditorUIController.initThemeColors && EditorUIController.initThemeColors(); - let selectedObjects = Common.EditorApi.get().asc_getGraphicObjectProps(); + EditorUIController.initCellInfo && EditorUIController.initCellInfo(this.props); - if(selectedObjects.length) { - storeFocusObjects.resetFocusObjects(selectedObjects); + EditorUIController.initEditorStyles && EditorUIController.initEditorStyles(this.props.storeCellSettings); - // Chart Settings - - if (storeFocusObjects.chartObject) { - storeChartSettings.updateChartStyles(this.api.asc_getChartPreviews(storeFocusObjects.chartObject.get_ChartProperties().getType())); - } - } - }); + EditorUIController.initFonts && EditorUIController.initFonts(this.props); + const styleSize = this.props.storeCellSettings.styleSize; this.api.asc_setThumbnailStylesSizes(styleSize.width, styleSize.height); - this.api.asc_registerCallback('asc_onInitEditorFonts', (fonts, select) => { - storeCellSettings.initEditorFonts(fonts, select); - storeTextSettings.initEditorFonts(fonts, select); - }); - - this.api.asc_registerCallback('asc_onEditorSelectionChanged', fontObj => { - console.log(fontObj) - storeCellSettings.initFontInfo(fontObj); - storeTextSettings.initFontInfo(fontObj); - }); - - this.api.asc_registerCallback('asc_onInitEditorStyles', styles => { - storeCellSettings.initCellStyles(styles); - }); - - this.api.asc_registerCallback('asc_onSendThemeColors', (colors, standart_colors) => { - Common.Utils.ThemeColor.setColors(colors, standart_colors); - }); - // Spreadsheet Settings this.api.asc_registerCallback('asc_onSendThemeColorSchemes', schemes => { - storeSpreadsheetSettings.addSchemes(schemes); + this.props.storeSpreadsheetSettings.addSchemes(schemes); }); // Downloaded Advanced Options diff --git a/apps/spreadsheeteditor/mobile/src/store/focusObjects.js b/apps/spreadsheeteditor/mobile/src/store/focusObjects.js index a5d710292..936293cb0 100644 --- a/apps/spreadsheeteditor/mobile/src/store/focusObjects.js +++ b/apps/spreadsheeteditor/mobile/src/store/focusObjects.js @@ -61,140 +61,19 @@ export class storeFocusObjects { } get selections () { - const _selections = []; - - let isCell, isRow, isCol, isAll, isChart, isImage, isTextShape, isShape, isTextChart, - selType = this._cellInfo.asc_getSelectionType(), - isObjLocked = false; - - switch (selType) { - case Asc.c_oAscSelectionType.RangeCells: isCell = true; break; - case Asc.c_oAscSelectionType.RangeRow: isRow = true; break; - case Asc.c_oAscSelectionType.RangeCol: isCol = true; break; - case Asc.c_oAscSelectionType.RangeMax: isAll = true; break; - case Asc.c_oAscSelectionType.RangeImage: isImage = true; break; - case Asc.c_oAscSelectionType.RangeShape: isShape = true; break; - case Asc.c_oAscSelectionType.RangeChart: isChart = true; break; - case Asc.c_oAscSelectionType.RangeChartText:isTextChart = true; break; - case Asc.c_oAscSelectionType.RangeShapeText: isTextShape = true; break; - } - - if (isImage || isShape || isChart) { - isImage = isShape = isChart = false; - let has_chartprops = false; - let selectedObjects = Common.EditorApi.get().asc_getGraphicObjectProps(); - - for (let i = 0; i < selectedObjects.length; i++) { - if (selectedObjects[i].asc_getObjectType() == Asc.c_oAscTypeSelectElement.Image) { - const elValue = selectedObjects[i].asc_getObjectValue(); - isObjLocked = isObjLocked || elValue.asc_getLocked(); - const shapeProps = elValue.asc_getShapeProperties(); - - if (shapeProps) { - if (shapeProps.asc_getFromChart()) { - isChart = true; - } else { - isShape = true; - - } - } else if (elValue.asc_getChartProperties()) { - isChart = true; - has_chartprops = true; - } else { - isImage = true; - } - } - } - } else if (isTextShape || isTextChart) { - const selectedObjects = Common.EditorApi.get().asc_getGraphicObjectProps(); - let isEquation = false; - - for (var i = 0; i < selectedObjects.length; i++) { - const elType = selectedObjects[i].asc_getObjectType(); - if (elType == Asc.c_oAscTypeSelectElement.Image) { - const value = selectedObjects[i].asc_getObjectValue(); - isObjLocked = isObjLocked || value.asc_getLocked(); - } else if (elType == Asc.c_oAscTypeSelectElement.Paragraph) { - } else if (elType == Asc.c_oAscTypeSelectElement.Math) { - isEquation = true; - } - } - } - if (isChart || isTextChart) { - _selections.push('chart'); - - if (isTextChart) { - _selections.push('text'); - } - } else if ((isShape || isTextShape) && !isImage) { - _selections.push('shape'); - - if (isTextShape) { - _selections.push('text'); - } - } else if (isImage) { - _selections.push('image'); - - if (isShape) { - _selections.push('shape'); - } - } else { - _selections.push('cell'); - - if (this._cellInfo.asc_getHyperlink()) { - _selections.push('hyperlink'); - } - } - return _selections; + return !!this.intf ? this.intf.getSelections() : null; } get shapeObject() { - const shapes = []; - for (let object of this._focusObjects) { - if (object.get_ObjectType() === Asc.c_oAscTypeSelectElement.Image) { - if (object.get_ObjectValue() && object.get_ObjectValue().get_ShapeProperties()) { - shapes.push(object); - } - } - } - if (shapes.length > 0) { - const object = shapes[shapes.length - 1]; // get top - return object.get_ObjectValue(); - } else { - return undefined; - } + return !!this.intf ? this.intf.getShapeObject() : null; } get imageObject() { - const images = []; - for (let object of this._focusObjects) { - if (object.get_ObjectType() === Asc.c_oAscTypeSelectElement.Image) { - images.push(object); - } - } - if (images.length > 0) { - const object = images[images.length - 1]; // get top - return object.get_ObjectValue(); - } else { - return undefined; - } + return !!this.intf ? this.intf.getImageObject() : null; } get chartObject() { - const charts = []; - for (let object of this._focusObjects) { - if (object.get_ObjectType() === Asc.c_oAscTypeSelectElement.Image) { - if (object.get_ObjectValue() && object.get_ObjectValue().get_ChartProperties()) { - charts.push(object); - } - } - } - if (charts.length > 0) { - const object = charts[charts.length - 1]; // get top - return object.get_ObjectValue(); - } else { - return undefined; - } + return !!this.intf ? this.intf.getChartObject() : null; } } \ No newline at end of file From 26523317e7a5a66e4b76b504f1f1edb9e64c4b05 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Wed, 21 Apr 2021 21:03:14 +0300 Subject: [PATCH 41/43] [PE mobile] Add translations --- apps/presentationeditor/mobile/locale/en.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/presentationeditor/mobile/locale/en.json b/apps/presentationeditor/mobile/locale/en.json index a4aaae940..44a1aa35b 100644 --- a/apps/presentationeditor/mobile/locale/en.json +++ b/apps/presentationeditor/mobile/locale/en.json @@ -138,6 +138,12 @@ "errorCopyCutPaste": "Copy, cut and paste actions using the context menu will be performed within the current file only.", "textDoNotShowAgain": "Don't show again" }, + "Toolbar": { + "dlgLeaveTitleText": "You leave the application", + "dlgLeaveMsgText": "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.", + "leaveButtonText": "Leave this Page", + "stayButtonText": "Stay on this Page" + }, "View": { "Settings": { "textDone": "Done", From cfbb8ce795ef5af699597d6410909c3ae6f5e3f0 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Wed, 21 Apr 2021 21:04:52 +0300 Subject: [PATCH 42/43] [SSE mobile] Add toolbar, add logo --- apps/spreadsheeteditor/mobile/locale/en.json | 6 + .../mobile/src/controller/Main.jsx | 6 + .../mobile/src/controller/Toolbar.jsx | 207 ++++++++++++++++++ .../mobile/src/page/main.jsx | 37 ++-- .../mobile/src/store/appOptions.js | 2 - .../mobile/src/view/Toolbar.jsx | 33 +++ 6 files changed, 269 insertions(+), 22 deletions(-) create mode 100644 apps/spreadsheeteditor/mobile/src/controller/Toolbar.jsx create mode 100644 apps/spreadsheeteditor/mobile/src/view/Toolbar.jsx diff --git a/apps/spreadsheeteditor/mobile/locale/en.json b/apps/spreadsheeteditor/mobile/locale/en.json index e1b4b968c..773ef247b 100644 --- a/apps/spreadsheeteditor/mobile/locale/en.json +++ b/apps/spreadsheeteditor/mobile/locale/en.json @@ -29,6 +29,12 @@ "menuEdit": "Edit", "menuDelete": "Delete" }, + "Toolbar": { + "dlgLeaveTitleText": "You leave the application", + "dlgLeaveMsgText": "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.", + "leaveButtonText": "Leave this Page", + "stayButtonText": "Stay on this Page" + }, "View" : { "Add" : { "textChart": "Chart", diff --git a/apps/spreadsheeteditor/mobile/src/controller/Main.jsx b/apps/spreadsheeteditor/mobile/src/controller/Main.jsx index afd6c2524..2b34515cb 100644 --- a/apps/spreadsheeteditor/mobile/src/controller/Main.jsx +++ b/apps/spreadsheeteditor/mobile/src/controller/Main.jsx @@ -278,6 +278,8 @@ class MainController extends Component { me.api.asc_getWorksheetsCount(); me.api.asc_showWorksheet(me.api.asc_getActiveWorksheetIndex()); + this.applyLicense(); + Common.Gateway.documentReady(); f7.emit('resize'); } @@ -291,6 +293,10 @@ class MainController extends Component { // } } + applyLicense () { + Common.Notifications.trigger('toolbar:activatecontrols'); + } + render() { return ( diff --git a/apps/spreadsheeteditor/mobile/src/controller/Toolbar.jsx b/apps/spreadsheeteditor/mobile/src/controller/Toolbar.jsx new file mode 100644 index 000000000..16dd1b657 --- /dev/null +++ b/apps/spreadsheeteditor/mobile/src/controller/Toolbar.jsx @@ -0,0 +1,207 @@ +import React, { useEffect, useState } from 'react'; +import { inject } from 'mobx-react'; +import { f7 } from 'framework7-react'; +import { useTranslation } from 'react-i18next'; +import ToolbarView from "../view/Toolbar"; + +const ToolbarController = inject('storeAppOptions', 'users', 'storeSpreadsheetInfo')(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 docTitle = props.storeSpreadsheetInfo.dataDoc ? props.storeSpreadsheetInfo.dataDoc.title : ''; + + useEffect(() => { + const onDocumentReady = () => { + const api = Common.EditorApi.get(); + api.asc_registerCallback('asc_onCanUndoChanged', onApiCanUndo); + api.asc_registerCallback('asc_onCanRedoChanged', onApiCanRedo); + api.asc_registerCallback('asc_onSelectionChanged', onApiSelectionChanged); + api.asc_registerCallback('asc_onWorkbookLocked', onApiSelectionChanged); + api.asc_registerCallback('asc_onWorksheetLocked', onApiSelectionChanged); + api.asc_registerCallback('asc_onActiveSheetChanged', onApiActiveSheetChanged); + api.asc_registerCallback('asc_onCoAuthoringDisconnect', onCoAuthoringDisconnect); + + Common.Notifications.on('api:disconnect', onCoAuthoringDisconnect); + Common.Notifications.on('toolbar:activatecontrols', activateControls); + Common.Notifications.on('toolbar:deactivateeditcontrols', deactivateEditControls); + Common.Notifications.on('goback', goBack); + Common.Notifications.on('sheet:active', onApiActiveSheetChanged); + }; + if ( !Common.EditorApi ) { + Common.Notifications.on('document:ready', onDocumentReady); + Common.Gateway.on('init', loadConfig); + } else { + onDocumentReady(); + } + + return () => { + Common.Notifications.off('document:ready', onDocumentReady); + Common.Notifications.off('api:disconnect', onCoAuthoringDisconnect); + Common.Notifications.off('toolbar:activatecontrols', activateControls); + Common.Notifications.off('toolbar:deactivateeditcontrols', deactivateEditControls); + Common.Notifications.off('goback', goBack); + Common.Notifications.off('sheet:active', onApiActiveSheetChanged); + + const api = Common.EditorApi.get(); + api.asc_unregisterCallback('asc_onCanUndoChanged', onApiCanUndo); + api.asc_unregisterCallback('asc_onCanRedoChanged', onApiCanRedo); + //api.asc_unregisterCallback('asc_onSelectionChanged', onApiSelectionChanged); TO DO + api.asc_unregisterCallback('asc_onWorkbookLocked', onApiSelectionChanged); + api.asc_unregisterCallback('asc_onWorksheetLocked', onApiSelectionChanged); + api.asc_unregisterCallback('asc_onActiveSheetChanged', onApiActiveSheetChanged); + api.asc_unregisterCallback('asc_onCoAuthoringDisconnect', onCoAuthoringDisconnect); + } + }); + + // Back button + const [isShowBack, setShowBack] = useState(false); + const loadConfig = (data) => { + if (data && data.config && data.config.canBackToFolder !== false && + data.config.customization && data.config.customization.goback && + (data.config.customization.goback.url || data.config.customization.goback.requestClose && data.config.canRequestClose)) { + setShowBack(true); + } + }; + const onBack = () => { + const api = Common.EditorApi.get(); + if (api.asc_isDocumentModified()) { + f7.dialog.create({ + title : _t.dlgLeaveTitleText, + text : _t.dlgLeaveMsgText, + verticalButtons: true, + buttons : [ + { + text: _t.leaveButtonText, + onClick: function() { + goBack(); + } + }, + { + text: _t.stayButtonText, + bold: true + } + ] + }).open(); + } else { + goBack(); + } + }; + const goBack = (current) => { + //if ( !Common.Controllers.Desktop.process('goback') ) { + if (appOptions.customization.goback.requestClose && appOptions.canRequestClose) { + Common.Gateway.requestClose(); + } else { + const href = appOptions.customization.goback.url; + if (!current && appOptions.customization.goback.blank !== false) { + window.open(href, "_blank"); + } else { + parent.location.href = href; + } + } + //} + } + + // Undo and Redo + const [isCanUndo, setCanUndo] = useState(false); + const [isCanRedo, setCanRedo] = useState(false); + const onApiCanUndo = (can) => { + if (isDisconnected) return; + setCanUndo(can); + }; + const onApiCanRedo = (can) => { + if (isDisconnected) return; + setCanRedo(can); + }; + const onUndo = () => { + const api = Common.EditorApi.get(); + if (api) { + api.asc_Undo(); + } + }; + const onRedo = () => { + const api = Common.EditorApi.get(); + if (api) { + api.asc_Redo(); + } + } + + const [disabledEditControls, setDisabledEditControls] = useState(false); + const onApiSelectionChanged = (cellInfo) => { + if (isDisconnected) return; + + const api = Common.EditorApi.get(); + const info = !!cellInfo ? cellInfo : api.asc_getCellInfo(); + let islocked = false; + + switch (info.asc_getSelectionType()) { + case Asc.c_oAscSelectionType.RangeChart: + case Asc.c_oAscSelectionType.RangeImage: + case Asc.c_oAscSelectionType.RangeShape: + case Asc.c_oAscSelectionType.RangeChartText: + case Asc.c_oAscSelectionType.RangeShapeText: + const objects = api.asc_getGraphicObjectProps(); + for ( let i in objects ) { + if ( objects[i].asc_getObjectType() == Asc.c_oAscTypeSelectElement.Image ) { + if ((islocked = objects[i].asc_getObjectValue().asc_getLocked())) + break; + } + } + break; + default: + islocked = info.asc_getLocked(); + } + + setDisabledEditControls(islocked); + }; + + const onApiActiveSheetChanged = (index) => { + Common.Notifications.trigger('comments:filterchange', ['doc', 'sheet' + Common.EditorApi.get().asc_getWorksheetId(index)], false ); + }; + + const [disabledSettings, setDisabledSettings] = useState(false); + const deactivateEditControls = (enableDownload) => { + setDisabledEditControls(true); + if (enableDownload) { + //DE.getController('Settings').setMode({isDisconnected: true, enableDownload: enableDownload}); + } else { + setDisabledSettings(true); + } + }; + + + const [disabledControls, setDisabledControls] = useState(true); + const activateControls = () => { + setDisabledControls(false); + }; + + const onCoAuthoringDisconnect = (enableDownload) => { + deactivateEditControls(enableDownload); + setCanUndo(false); + setCanRedo(false); + f7.popover.close(); + f7.sheet.close(); + f7.popup.close(); + }; + + return ( + + ) +}); + +export {ToolbarController as Toolbar}; \ No newline at end of file diff --git a/apps/spreadsheeteditor/mobile/src/page/main.jsx b/apps/spreadsheeteditor/mobile/src/page/main.jsx index 2f7b3713d..e02028e24 100644 --- a/apps/spreadsheeteditor/mobile/src/page/main.jsx +++ b/apps/spreadsheeteditor/mobile/src/page/main.jsx @@ -1,21 +1,21 @@ import React, { Component } from 'react'; -import { Page, View, Navbar, NavLeft, NavRight, Link, Icon } from 'framework7-react'; +import { Page, View, Navbar, Subnavbar, Icon } from 'framework7-react'; +import { observer, inject } from "mobx-react"; -// import EditOptions from '../view/edit/Edit'; import Settings from '../view/settings/Settings'; import CollaborationView from '../../../../common/mobile/lib/view/collaboration/Collaboration.jsx' import CellEditor from '../controller/CellEditor'; import Statusbar from '../controller/StatusBar' import AddOptions from "../view/add/Add"; import EditOptions from "../view/edit/Edit"; -import { Device } from '../../../../common/mobile/utils/device'; import { Search, SearchSettings } from '../controller/Search'; import { f7 } from 'framework7-react'; import {FunctionGroups} from "../controller/add/AddFunction"; import ContextMenu from '../controller/ContextMenu'; +import { Toolbar } from "../controller/Toolbar"; -export default class MainPage extends Component { +class MainPage extends Component { constructor(props) { super(props); this.state = { @@ -61,23 +61,18 @@ export default class MainPage extends Component { }; render() { + const appOptions = this.props.storeAppOptions; + const config = appOptions.config; + const showLogo = !(appOptions.canBrandingExt && (config.customization && (config.customization.loaderName || config.customization.loaderLogo))); return ( - + {/* Top Navbar */} - - {/*
*/} - - - - - - this.handleClickToOpenOptions('edit')}> - this.handleClickToOpenOptions('add')}> - { Device.phone ? null : } - this.handleClickToOpenOptions('coauth')}> - this.handleClickToOpenOptions('settings')}> - - + + {showLogo &&
} + + + +
this.handleClickToOpenOptions('add', {panels: panels, button: button})}/> {/* Page content */} @@ -106,4 +101,6 @@ export default class MainPage extends Component {
) } -}; \ No newline at end of file +} + +export default inject("storeAppOptions")(observer(MainPage)); \ No newline at end of file diff --git a/apps/spreadsheeteditor/mobile/src/store/appOptions.js b/apps/spreadsheeteditor/mobile/src/store/appOptions.js index bb3f69a2d..75900a131 100644 --- a/apps/spreadsheeteditor/mobile/src/store/appOptions.js +++ b/apps/spreadsheeteditor/mobile/src/store/appOptions.js @@ -12,8 +12,6 @@ export class storeAppOptions { isEdit = false; config = {}; - - isEdit = false; canViewComments = false; setConfigOptions (config) { diff --git a/apps/spreadsheeteditor/mobile/src/view/Toolbar.jsx b/apps/spreadsheeteditor/mobile/src/view/Toolbar.jsx new file mode 100644 index 000000000..26887d95b --- /dev/null +++ b/apps/spreadsheeteditor/mobile/src/view/Toolbar.jsx @@ -0,0 +1,33 @@ +import React, {Fragment} from 'react'; +import {NavLeft, NavRight, NavTitle, Link, Icon} from 'framework7-react'; +import { Device } from '../../../../common/mobile/utils/device'; +import EditorUIController from '../lib/patch' + +const ToolbarView = props => { + return ( + + + {props.isShowBack && } + {props.isEdit && EditorUIController.toolbarOptions && EditorUIController.toolbarOptions.getUndoRedo({ + disabledUndo: !props.isCanUndo, + disabledRedo: !props.isCanRedo, + onUndoClick: props.onUndo, + onRedoClick: props.onRedo + })} + + {!Device.phone && {props.docTitle}} + + {props.isEdit && EditorUIController.toolbarOptions && EditorUIController.toolbarOptions.getEditOptions({ + disabled: props.disabledEditControls || props.disabledControls, + onEditClick: () => props.openOptions('edit'), + onAddClick: () => props.openOptions('add') + })} + { Device.phone ? null : } + {props.displayCollaboration && props.openOptions('coauth')}>} + props.openOptions('settings')}> + + + ) +}; + +export default ToolbarView; \ No newline at end of file From 588a7f03863ebf9ec3251a36decc8b4e280dda59 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Thu, 22 Apr 2021 13:54:26 +0300 Subject: [PATCH 43/43] [SSE mobile] Moved edit functions of context menu to private branch --- .../mobile/src/controller/ContextMenu.jsx | 243 ++++-------------- 1 file changed, 45 insertions(+), 198 deletions(-) diff --git a/apps/spreadsheeteditor/mobile/src/controller/ContextMenu.jsx b/apps/spreadsheeteditor/mobile/src/controller/ContextMenu.jsx index 39dad5fe2..7965086fb 100644 --- a/apps/spreadsheeteditor/mobile/src/controller/ContextMenu.jsx +++ b/apps/spreadsheeteditor/mobile/src/controller/ContextMenu.jsx @@ -7,6 +7,7 @@ import { LocalStorage } from '../../../../common/mobile/utils/LocalStorage'; 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 => ({ isEdit: stores.storeAppOptions.isEdit, @@ -61,11 +62,14 @@ class ContextMenu extends ContextMenuController { super.onMenuItemClick(action); + if ( EditorUIController.ContextMenu && EditorUIController.ContextMenu.handleMenuItemClick(this, action) ) + return; + const api = Common.EditorApi.get(); const info = api.asc_getCellInfo(); switch (action) { case 'cut': - if (!api.asc_Cut() && !LocalStorage.getBool("sse-hide-copy-cut-paste-warning")) { + if (!LocalStorage.getBool("sse-hide-copy-cut-paste-warning")) { this.showCopyCutPasteModal(); } break; @@ -75,55 +79,13 @@ class ContextMenu extends ContextMenuController { } break; case 'paste': - if (!api.asc_Paste() && !LocalStorage.getBool("sse-hide-copy-cut-paste-warning")) { + if (!LocalStorage.getBool("sse-hide-copy-cut-paste-warning")) { this.showCopyCutPasteModal(); } break; - case 'addcomment': - Common.Notifications.trigger('addcomment'); - break; case 'viewcomment': Common.Notifications.trigger('viewcomment'); break; - case 'del': - api.asc_emptyCells(Asc.c_oAscCleanOptions.All); - break; - case 'wrap': - api.asc_setCellTextWrap(true); - break; - case 'unwrap': - api.asc_setCellTextWrap(false); - break; - case 'edit': - setTimeout(() => { - this.props.openOptions('edit'); - }, 0); - break; - case 'merge': - if (api.asc_mergeCellsDataLost(Asc.c_oAscMergeOptions.Merge)) { - setTimeout(() => { - f7.dialog.confirm(_t.warnMergeLostData, _t.notcriticalErrorTitle, () => { - api.asc_mergeCells(Asc.c_oAscMergeOptions.Merge); - }); - }, 0); - } else { - api.asc_mergeCells(Asc.c_oAscMergeOptions.Merge); - } - break; - case 'unmerge': - api.asc_mergeCells(Asc.c_oAscMergeOptions.None); - break; - case 'hide': - api[info.asc_getSelectionType() == Asc.c_oAscSelectionType.RangeRow ? 'asc_hideRows' : 'asc_hideColumns'](); - break; - case 'show': - api[info.asc_getSelectionType() == Asc.c_oAscSelectionType.RangeRow ? 'asc_showRows' : 'asc_showColumns'](); - break; - case 'addlink': - setTimeout(() => { - this.props.openOptions('add', 'link'); - }, 400) - break; case 'openlink': const linkinfo = info.asc_getHyperlink(); if ( linkinfo.asc_getType() == Asc.c_oAscHyperlinkType.RangeLink ) { @@ -145,12 +107,22 @@ class ContextMenu extends ContextMenuController { api.asc_getUrlType(url) > 0 && this.openLink(url); } break; - case 'freezePanes': - api.asc_freezePane(); - break; } + } - console.log("click context menu item: " + action); + onMergeCells() { + const { t } = this.props; + const _t = t("ContextMenu", { returnObjects: true }); + const api = Common.EditorApi.get(); + if (api.asc_mergeCellsDataLost(Asc.c_oAscMergeOptions.Merge)) { + setTimeout(() => { + f7.dialog.confirm(_t.warnMergeLostData, _t.notcriticalErrorTitle, () => { + api.asc_mergeCells(Asc.c_oAscMergeOptions.Merge); + }); + }, 0); + } else { + api.asc_mergeCells(Asc.c_oAscMergeOptions.Merge); + } } showCopyCutPasteModal() { @@ -198,33 +170,35 @@ class ContextMenu extends ContextMenuController { const { t } = this.props; const _t = t("ContextMenu", { returnObjects: true }); - const { isEdit, canViewComments, isDisconnected } = this.props; + const { isEdit } = this.props; - const api = Common.EditorApi.get(); - const cellinfo = api.asc_getCellInfo(); + if (isEdit && EditorUIController.ContextMenu) { + return EditorUIController.ContextMenu.mapMenuItems(this); + } else { + const {canViewComments } = this.props; - const itemsIcon = []; - const itemsText = []; + const api = Common.EditorApi.get(); + const cellinfo = api.asc_getCellInfo(); - let iscellmenu, isrowmenu, iscolmenu, isallmenu, ischartmenu, isimagemenu, istextshapemenu, isshapemenu, istextchartmenu; - let iscelllocked = cellinfo.asc_getLocked(); - const seltype = cellinfo.asc_getSelectionType(); - const xfs = cellinfo.asc_getXfs(); - const isComments = cellinfo.asc_getComments().length > 0; //prohibit adding multiple comments in one cell; + const itemsIcon = []; + const itemsText = []; - switch (seltype) { - case Asc.c_oAscSelectionType.RangeCells: iscellmenu = true; break; - case Asc.c_oAscSelectionType.RangeRow: isrowmenu = true; break; - case Asc.c_oAscSelectionType.RangeCol: iscolmenu = true; break; - case Asc.c_oAscSelectionType.RangeMax: isallmenu = true; break; - case Asc.c_oAscSelectionType.RangeImage: isimagemenu = true; break; - case Asc.c_oAscSelectionType.RangeShape: isshapemenu = true; break; - case Asc.c_oAscSelectionType.RangeChart: ischartmenu = true; break; - case Asc.c_oAscSelectionType.RangeChartText: istextchartmenu = true; break; - case Asc.c_oAscSelectionType.RangeShapeText: istextshapemenu = true; break; - } + let iscellmenu, isrowmenu, iscolmenu, isallmenu, ischartmenu, isimagemenu, istextshapemenu, isshapemenu, istextchartmenu; + const seltype = cellinfo.asc_getSelectionType(); + const isComments = cellinfo.asc_getComments().length > 0; //prohibit adding multiple comments in one cell; + + switch (seltype) { + case Asc.c_oAscSelectionType.RangeCells: iscellmenu = true; break; + case Asc.c_oAscSelectionType.RangeRow: isrowmenu = true; break; + case Asc.c_oAscSelectionType.RangeCol: iscolmenu = true; break; + case Asc.c_oAscSelectionType.RangeMax: isallmenu = true; break; + case Asc.c_oAscSelectionType.RangeImage: isimagemenu = true; break; + case Asc.c_oAscSelectionType.RangeShape: isshapemenu = true; break; + case Asc.c_oAscSelectionType.RangeChart: ischartmenu = true; break; + case Asc.c_oAscSelectionType.RangeChartText: istextchartmenu = true; break; + case Asc.c_oAscSelectionType.RangeShapeText: istextshapemenu = true; break; + } - if (!isEdit) { if (iscellmenu || istextchartmenu || istextshapemenu) { itemsIcon.push({ event: 'copy', @@ -243,136 +217,9 @@ class ContextMenu extends ContextMenuController { event: 'viewcomment' }); } - } else { - if (!iscelllocked && (isimagemenu || isshapemenu || ischartmenu || istextshapemenu || istextchartmenu)) { - api.asc_getGraphicObjectProps().every((object) => { - if (object.asc_getObjectType() == Asc.c_oAscTypeSelectElement.Image) { - iscelllocked = object.asc_getObjectValue().asc_getLocked(); - } - return !iscelllocked; - }); - } - - if (iscelllocked || api.isCellEdited) { - itemsIcon.push({ - event: 'copy', - icon: 'icon-copy' - }); - - } else { - itemsIcon.push({ - event: 'cut', - icon: 'icon-cut' - }); - itemsIcon.push({ - event: 'copy', - icon: 'icon-copy' - }); - itemsIcon.push({ - event: 'paste', - icon: 'icon-paste' - }); - itemsText.push({ - caption: _t.menuDelete, - event: 'del' - }); - - if (isimagemenu || isshapemenu || ischartmenu || - istextshapemenu || istextchartmenu) { - itemsText.push({ - caption: _t.menuEdit, - event: 'edit' - }); - } else { - if (iscolmenu || isrowmenu) { - itemsText.push({ - caption: _t.menuHide, - event: 'hide' - }); - itemsText.push({ - caption: _t.menuShow, - event: 'show' - }); - } else if (iscellmenu) { - if (!iscelllocked) { - itemsText.push({ - caption: _t.menuCell, - event: 'edit' - }); - } - - if (cellinfo.asc_getMerge() == Asc.c_oAscMergeOptions.None) { - itemsText.push({ - caption: _t.menuMerge, - event: 'merge' - }); - } - - if (cellinfo.asc_getMerge() == Asc.c_oAscMergeOptions.Merge) { - itemsText.push({ - caption: _t.menuUnmerge, - event: 'unmerge' - }); - } - - itemsText.push( - xfs.asc_getWrapText() ? - { - caption: _t.menuUnwrap, - event: 'unwrap' - } : - { - caption: _t.menuWrap, - event: 'wrap' - }); - - if (cellinfo.asc_getHyperlink() && !cellinfo.asc_getMultiselect()) { - itemsText.push({ - caption: _t.menuOpenLink, - event: 'openlink' - }); - } else if (!cellinfo.asc_getHyperlink() && !cellinfo.asc_getMultiselect() && - !cellinfo.asc_getLockText() && !!cellinfo.asc_getText()) { - itemsText.push({ - caption: _t.menuAddLink, - event: 'addlink' - }); - } - } - - itemsText.push({ - caption: api.asc_getSheetViewSettings().asc_getIsFreezePane() ? _t.menuUnfreezePanes : _t.menuFreezePanes, - event: 'freezePanes' - }); - - } - - if (canViewComments) { - if (isComments) { - itemsText.push({ - caption: _t.menuViewComment, - event: 'viewcomment' - }); - } else if (iscellmenu) { - itemsText.push({ - caption: _t.menuAddComment, - event: 'addcomment' - }); - } - } - } + return itemsIcon.concat(itemsText); } - - - if ( Device.phone && itemsText.length > 2 ) { - this.extraItems = itemsText.splice(2,itemsText.length, { - caption: _t.menuMore, - event: 'showActionSheet' - }); - } - - return itemsIcon.concat(itemsText); } initExtraItems () {