From a92997107f237f0d1f4a4017a1736324a2980b5d Mon Sep 17 00:00:00 2001 From: SergeyEzhin Date: Wed, 11 Jan 2023 15:05:15 +0400 Subject: [PATCH 1/9] [DE mobile] Adding protection of document --- apps/documenteditor/mobile/locale/en.json | 11 +++ .../src/controller/settings/Protection.jsx | 37 +++++++++ .../mobile/src/less/icons-common.less | 6 ++ .../mobile/src/less/icons-material.less | 7 +- .../mobile/src/store/appOptions.js | 10 ++- .../mobile/src/view/Toolbar.jsx | 2 +- .../mobile/src/view/settings/Protection.jsx | 83 +++++++++++++++++++ .../mobile/src/view/settings/Settings.jsx | 12 ++- 8 files changed, 163 insertions(+), 5 deletions(-) create mode 100644 apps/documenteditor/mobile/src/controller/settings/Protection.jsx create mode 100644 apps/documenteditor/mobile/src/view/settings/Protection.jsx diff --git a/apps/documenteditor/mobile/locale/en.json b/apps/documenteditor/mobile/locale/en.json index c414be24b2..b2f1b38239 100644 --- a/apps/documenteditor/mobile/locale/en.json +++ b/apps/documenteditor/mobile/locale/en.json @@ -658,6 +658,17 @@ "textRightToLeft": "Right To Left", "textSearch": "Search", "textSettings": "Settings", + "textProtectDocument": "Protect Document", + "textUnprotect": "Unprotect", + "textSetPassword": "Set Password", + "textTypeEditing": "Type Of Editing", + "textNoChanges": "No changes (Read only)", + "textFillingForms": "Filling forms", + "textTrackedChanges": "Tracked changes", + "textPassword": "Password", + "textVerify": "Verify", + "textSave": "Save", + "textRequired": "Required", "textShowNotification": "Show Notification", "textSpaces": "Spaces", "textSpellcheck": "Spell Checking", diff --git a/apps/documenteditor/mobile/src/controller/settings/Protection.jsx b/apps/documenteditor/mobile/src/controller/settings/Protection.jsx new file mode 100644 index 0000000000..d41b9e8ff6 --- /dev/null +++ b/apps/documenteditor/mobile/src/controller/settings/Protection.jsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { Device } from '../../../../../common/mobile/utils/device'; +// import { withTranslation } from 'react-i18next'; +import { f7 } from "framework7-react"; +import ProtectionView from '../../view/settings/Protection'; + +class ProtectionController extends React.Component { + constructor(props) { + super(props); + this.onProtectDocument = this.onProtectDocument.bind(this); + } + + closeModal() { + if (Device.phone) { + f7.sheet.close('.settings-popup', false); + } else { + f7.popover.close('#settings-popover', false); + } + }; + + onProtectDocument(typeProtection, password) { + const api = Common.EditorApi.get(); + const protection = api.asc_getDocumentProtection() || new AscCommonWord.CDocProtect(); + + protection.asc_setEditType(typeProtection); + protection.asc_setPassword(password); + api.asc_setDocumentProtection(protection); + + this.closeModal(); + }; + + render() { + return + } +} + +export default ProtectionController; \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/less/icons-common.less b/apps/documenteditor/mobile/src/less/icons-common.less index 6d834af086..8651a11b28 100644 --- a/apps/documenteditor/mobile/src/less/icons-common.less +++ b/apps/documenteditor/mobile/src/less/icons-common.less @@ -54,4 +54,10 @@ i.icon { height: 22px; .encoded-svg-background(''); } + + &.icon-protect-document { + width: 22px; + height: 22px; + .encoded-svg-mask('') + } } \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/less/icons-material.less b/apps/documenteditor/mobile/src/less/icons-material.less index 2110bff3cf..9d3adb4741 100644 --- a/apps/documenteditor/mobile/src/less/icons-material.less +++ b/apps/documenteditor/mobile/src/less/icons-material.less @@ -79,7 +79,7 @@ height: 24px; .encoded-svg-mask('', @toolbar-icons); } - &.icon-back-reader-mode { + &.icon-check { width: 24px; height: 24px; .encoded-svg-mask('', @toolbar-icons); @@ -92,6 +92,11 @@ height: 24px; .encoded-svg-mask('', @fill-white); } + &.icon-check { + width: 24px; + height: 24px; + .encoded-svg-mask(''); + } &.icon-expand-down { width: 17px; height: 17px; diff --git a/apps/documenteditor/mobile/src/store/appOptions.js b/apps/documenteditor/mobile/src/store/appOptions.js index 8d4fae0651..8516358004 100644 --- a/apps/documenteditor/mobile/src/store/appOptions.js +++ b/apps/documenteditor/mobile/src/store/appOptions.js @@ -32,7 +32,10 @@ export class storeAppOptions { changeMobileView: action, isProtected: observable, - setProtection: action + setProtection: action, + + typeProtection: observable, + setTypeProtection: action }); } @@ -43,6 +46,11 @@ export class storeAppOptions { this.isProtected = value; } + typeProtection = 3; + setTypeProtection(type) { + this.typeProtection = type; + } + isMobileView = true; changeMobileView() { this.isMobileView = !this.isMobileView; diff --git a/apps/documenteditor/mobile/src/view/Toolbar.jsx b/apps/documenteditor/mobile/src/view/Toolbar.jsx index 619ee7f69b..540ecc6ae2 100644 --- a/apps/documenteditor/mobile/src/view/Toolbar.jsx +++ b/apps/documenteditor/mobile/src/view/Toolbar.jsx @@ -44,7 +44,7 @@ const ToolbarView = props => { return ( - {!isViewer && props.turnOnViewerMode()}>} + {!isViewer && props.turnOnViewerMode()}>} {(props.isShowBack && isViewer) && } {(Device.ios && props.isEdit && !isViewer) && EditorUIController.getUndoRedo && EditorUIController.getUndoRedo({ disabledUndo: !props.isCanUndo || isDisconnected, diff --git a/apps/documenteditor/mobile/src/view/settings/Protection.jsx b/apps/documenteditor/mobile/src/view/settings/Protection.jsx new file mode 100644 index 0000000000..db9d984e3b --- /dev/null +++ b/apps/documenteditor/mobile/src/view/settings/Protection.jsx @@ -0,0 +1,83 @@ +import React, { useState } from 'react'; +import { observer, inject } from "mobx-react"; +import { Device } from '../../../../../common/mobile/utils/device'; +import { Page, Navbar, List, ListItem, BlockTitle, Toggle, NavRight, f7, Link, ListInput, Icon, Block } from "framework7-react"; +import { useTranslation } from "react-i18next"; + +const ProtectionView = inject("storeAppOptions")(observer(props => { + const { t } = useTranslation(); + const _t = t("Settings", { returnObjects: true }); + const isIos = Device.ios; + const appOptions = props.storeAppOptions; + const typeProtection = appOptions.typeProtection; + const [isPassword, setPassword] = useState(false); + const [password, changePassword] = useState(''); + const [passwordRepeat, repeatPassword] = useState(''); + const isDisabledProtection = isPassword && ((!password.length || !passwordRepeat.length) || password !== passwordRepeat); + + return ( + + + + { + props.onProtectDocument(typeProtection, password); + }}> + {Device.android && } + + + + + + { + setPassword(!isPassword); + }} /> + + + {isPassword && + <> + + changePassword(e.target.value)} + className={isIos ? 'list-input-right' : ''} + /> + repeatPassword(e.target.value)} + className={isIos ? 'list-input-right' : ''} + /> + + +

If the password is forgotten or lost, it cannot be recovered.

+
+ + } + {t('Settings.textTypeEditing')} + + { + appOptions.setTypeProtection(Asc.c_oAscEDocProtect.ReadOnly); + }}> + { + appOptions.setTypeProtection(Asc.c_oAscEDocProtect.Forms); + }}> + { + appOptions.setTypeProtection(Asc.c_oAscEDocProtect.TrackedChanges); + }}> + { + appOptions.setTypeProtection(Asc.c_oAscEDocProtect.Comments); + }}> + + +

Allow only this type of editing in the document.

+
+
+ ) +})); + +export default ProtectionView; \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/view/settings/Settings.jsx b/apps/documenteditor/mobile/src/view/settings/Settings.jsx index 9ffb8d90a8..d6cf9d98a6 100644 --- a/apps/documenteditor/mobile/src/view/settings/Settings.jsx +++ b/apps/documenteditor/mobile/src/view/settings/Settings.jsx @@ -14,6 +14,7 @@ import { MacrosSettings, Direction } from "./ApplicationSettings"; import About from '../../../../../common/mobile/lib/view/About'; import NavigationController from '../../controller/settings/Navigation'; import SharingSettings from "../../../../../common/mobile/lib/view/SharingSettings"; +import ProtectionController from '../../controller/settings/Protection'; const routes = [ { @@ -65,17 +66,21 @@ const routes = [ }, // Direction - { path: '/direction/', component: Direction }, // Sharing Settings - { path: '/sharing-settings/', component: SharingSettings + }, + + // Protection + { + path: '/protection-document/', + component: ProtectionController } ]; @@ -150,6 +155,9 @@ const SettingsList = inject("storeAppOptions", "storeReview")(observer(props => } + + + { if(Device.phone) { onOpenNavigation(); From 74302f19d5c5d3aacfa4eea111a71e2afbfe87aa Mon Sep 17 00:00:00 2001 From: SergeyEzhin Date: Thu, 12 Jan 2023 17:32:21 +0400 Subject: [PATCH 2/9] [DE mobile] Added unprotection and protection view --- apps/documenteditor/mobile/locale/en.json | 6 +- .../mobile/src/controller/Error.jsx | 4 + .../settings/DocumentProtection.jsx | 37 +++++++++ .../src/controller/settings/Protection.jsx | 70 +++++++++++----- .../mobile/src/less/icons-common.less | 14 +++- .../src/view/settings/DocumentProtection.jsx | 83 +++++++++++++++++++ .../mobile/src/view/settings/Protection.jsx | 67 +-------------- .../mobile/src/view/settings/Settings.jsx | 12 ++- 8 files changed, 203 insertions(+), 90 deletions(-) create mode 100644 apps/documenteditor/mobile/src/controller/settings/DocumentProtection.jsx create mode 100644 apps/documenteditor/mobile/src/view/settings/DocumentProtection.jsx diff --git a/apps/documenteditor/mobile/locale/en.json b/apps/documenteditor/mobile/locale/en.json index b2f1b38239..b4c0904b85 100644 --- a/apps/documenteditor/mobile/locale/en.json +++ b/apps/documenteditor/mobile/locale/en.json @@ -427,7 +427,8 @@ "unknownErrorText": "Unknown error.", "uploadImageExtMessage": "Unknown image format.", "uploadImageFileCountMessage": "No images uploaded.", - "uploadImageSizeMessage": "The image is too big. The maximum size is 25 MB." + "uploadImageSizeMessage": "The image is too big. The maximum size is 25 MB.", + "errorPasswordIsNotCorrect": "The password you supplied is not correct. Verify that the CAPS LOCK key is off and be sure to use the correct capitalization." }, "LongActions": { "applyChangesTextText": "Loading data...", @@ -658,7 +659,10 @@ "textRightToLeft": "Right To Left", "textSearch": "Search", "textSettings": "Settings", + "textProtection": "Protection", "textProtectDocument": "Protect Document", + "titleDialogUnprotect": "Unprotect Document", + "textDialogUnprotect": "Enter a password to unprotect document", "textUnprotect": "Unprotect", "textSetPassword": "Set Password", "textTypeEditing": "Type Of Editing", diff --git a/apps/documenteditor/mobile/src/controller/Error.jsx b/apps/documenteditor/mobile/src/controller/Error.jsx index 8fe766a05e..28ad038b47 100644 --- a/apps/documenteditor/mobile/src/controller/Error.jsx +++ b/apps/documenteditor/mobile/src/controller/Error.jsx @@ -107,6 +107,10 @@ const ErrorController = inject('storeAppOptions','storeDocumentInfo')(({storeApp config.msg = _t.errorFilePassProtect; break; + case Asc.c_oAscError.ID.PasswordIsNotCorrect: + config.msg = t('Error.errorPasswordIsNotCorrect'); + break; + case Asc.c_oAscError.ID.StockChartError: config.msg = _t.errorStockChart; break; diff --git a/apps/documenteditor/mobile/src/controller/settings/DocumentProtection.jsx b/apps/documenteditor/mobile/src/controller/settings/DocumentProtection.jsx new file mode 100644 index 0000000000..6f8bbef3d8 --- /dev/null +++ b/apps/documenteditor/mobile/src/controller/settings/DocumentProtection.jsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { Device } from '../../../../../common/mobile/utils/device'; +// import { withTranslation } from 'react-i18next'; +import ProtectionDocumentView from '../../view/settings/DocumentProtection'; +import { f7 } from "framework7-react"; + +class ProtectionDocumentController extends React.Component { + constructor(props) { + super(props); + this.onProtectDocument = this.onProtectDocument.bind(this); + } + + closeModal() { + if (Device.phone) { + f7.sheet.close('.settings-popup', false); + } else { + f7.popover.close('#settings-popover', false); + } + }; + + onProtectDocument(typeProtection, password) { + const api = Common.EditorApi.get(); + const protection = api.asc_getDocumentProtection() || new AscCommonWord.CDocProtect(); + + protection.asc_setEditType(typeProtection); + protection.asc_setPassword(password); + api.asc_setDocumentProtection(protection); + + this.closeModal(); + }; + + render() { + return + } +} + +export default ProtectionDocumentController; \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/controller/settings/Protection.jsx b/apps/documenteditor/mobile/src/controller/settings/Protection.jsx index d41b9e8ff6..e6ccec3abc 100644 --- a/apps/documenteditor/mobile/src/controller/settings/Protection.jsx +++ b/apps/documenteditor/mobile/src/controller/settings/Protection.jsx @@ -1,37 +1,65 @@ import React from 'react'; -import { Device } from '../../../../../common/mobile/utils/device'; -// import { withTranslation } from 'react-i18next'; -import { f7 } from "framework7-react"; +import { observer, inject } from "mobx-react"; import ProtectionView from '../../view/settings/Protection'; +import { withTranslation } from 'react-i18next'; +import { f7 } from "framework7-react"; +import { Device } from '../../../../../common/mobile/utils/device'; class ProtectionController extends React.Component { constructor(props) { super(props); - this.onProtectDocument = this.onProtectDocument.bind(this); + this.onProtectClick = this.onProtectClick.bind(this); } - closeModal() { - if (Device.phone) { - f7.sheet.close('.settings-popup', false); - } else { - f7.popover.close('#settings-popover', false); - } - }; - - onProtectDocument(typeProtection, password) { + onProtectClick() { const api = Common.EditorApi.get(); - const protection = api.asc_getDocumentProtection() || new AscCommonWord.CDocProtect(); + const { t } = this.props; + const appOptions = this.props.storeAppOptions; + const isProtected = appOptions.isProtected; + let propsProtection = api.asc_getDocumentProtection(); + const isPassword = propsProtection?.asc_getIsPassword(); - protection.asc_setEditType(typeProtection); - protection.asc_setPassword(password); - api.asc_setDocumentProtection(protection); + if(isProtected) { + if(propsProtection && isPassword) { + f7.dialog.create({ + title: t('Settings.titleDialogUnprotect'), + text: t('Settings.textDialogUnprotect'), + content: Device.ios ? + '
' : '
', + cssClass: 'dlg-adv-options', + buttons: [ + { + text: t('Settings.textCancel') + }, + { + text: t('Settings.textOk'), + onClick: () => { + const passwordValue = document.querySelector('#protection-password')?.value; + + if(passwordValue) { + propsProtection.asc_setEditType(Asc.c_oAscEDocProtect.None); + propsProtection.asc_setPassword(passwordValue); + api.asc_setDocumentProtection(propsProtection); + } + } + } + ] + }).open(); + } else { + if (!propsProtection) + propsProtection = new AscCommonWord.CDocProtect(); - this.closeModal(); - }; + propsProtection.asc_setEditType(Asc.c_oAscEDocProtect.None); + api.asc_setDocumentProtection(props); + } + } else { + f7.views.current.router.navigate('/protect'); + } + } render() { - return + return } } -export default ProtectionController; \ No newline at end of file +export default inject('storeAppOptions')(observer(withTranslation()(ProtectionController))); \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/less/icons-common.less b/apps/documenteditor/mobile/src/less/icons-common.less index 8651a11b28..fb5710022c 100644 --- a/apps/documenteditor/mobile/src/less/icons-common.less +++ b/apps/documenteditor/mobile/src/less/icons-common.less @@ -58,6 +58,18 @@ i.icon { &.icon-protect-document { width: 22px; height: 22px; - .encoded-svg-mask('') + .encoded-svg-mask(''); + } + + &.icon-protection { + width: 22px; + height: 22px; + .encoded-svg-mask(''); + } + + &.icon-encrypt-file { + width: 22px; + height: 22px; + .encoded-svg-mask(''); } } \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/view/settings/DocumentProtection.jsx b/apps/documenteditor/mobile/src/view/settings/DocumentProtection.jsx new file mode 100644 index 0000000000..489250a5ee --- /dev/null +++ b/apps/documenteditor/mobile/src/view/settings/DocumentProtection.jsx @@ -0,0 +1,83 @@ +import React, { useState } from 'react'; +import { observer, inject } from "mobx-react"; +import { Device } from '../../../../../common/mobile/utils/device'; +import { Page, Navbar, List, ListItem, BlockTitle, Toggle, NavRight, f7, Link, ListInput, Icon, Block } from "framework7-react"; +import { useTranslation } from "react-i18next"; + +const ProtectionDocumentView = inject("storeAppOptions")(observer(props => { + const { t } = useTranslation(); + const _t = t("Settings", { returnObjects: true }); + const isIos = Device.ios; + const appOptions = props.storeAppOptions; + const typeProtection = appOptions.typeProtection; + const [isPassword, setPassword] = useState(false); + const [password, changePassword] = useState(''); + const [passwordRepeat, repeatPassword] = useState(''); + const isDisabledProtection = isPassword && ((!password.length || !passwordRepeat.length) || password !== passwordRepeat); + + return ( + + + + { + props.onProtectDocument(typeProtection, password); + }}> + {Device.android && } + + + + + + { + setPassword(!isPassword); + }} /> + + + {isPassword && + <> + + changePassword(e.target.value)} + className={isIos ? 'list-input-right' : ''} + /> + repeatPassword(e.target.value)} + className={isIos ? 'list-input-right' : ''} + /> + + +

If the password is forgotten or lost, it cannot be recovered.

+
+ + } + {t('Settings.textTypeEditing')} + + { + appOptions.setTypeProtection(Asc.c_oAscEDocProtect.ReadOnly); + }}> + { + appOptions.setTypeProtection(Asc.c_oAscEDocProtect.Forms); + }}> + { + appOptions.setTypeProtection(Asc.c_oAscEDocProtect.TrackedChanges); + }}> + { + appOptions.setTypeProtection(Asc.c_oAscEDocProtect.Comments); + }}> + + +

Allow only this type of editing in the document.

+
+
+ ) +})); + +export default ProtectionDocumentView; \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/view/settings/Protection.jsx b/apps/documenteditor/mobile/src/view/settings/Protection.jsx index db9d984e3b..02c3749e4e 100644 --- a/apps/documenteditor/mobile/src/view/settings/Protection.jsx +++ b/apps/documenteditor/mobile/src/view/settings/Protection.jsx @@ -1,81 +1,22 @@ import React, { useState } from 'react'; import { observer, inject } from "mobx-react"; -import { Device } from '../../../../../common/mobile/utils/device'; import { Page, Navbar, List, ListItem, BlockTitle, Toggle, NavRight, f7, Link, ListInput, Icon, Block } from "framework7-react"; import { useTranslation } from "react-i18next"; const ProtectionView = inject("storeAppOptions")(observer(props => { const { t } = useTranslation(); const _t = t("Settings", { returnObjects: true }); - const isIos = Device.ios; const appOptions = props.storeAppOptions; - const typeProtection = appOptions.typeProtection; - const [isPassword, setPassword] = useState(false); - const [password, changePassword] = useState(''); - const [passwordRepeat, repeatPassword] = useState(''); - const isDisabledProtection = isPassword && ((!password.length || !passwordRepeat.length) || password !== passwordRepeat); + const isProtected = appOptions.isProtected; return ( - - - { - props.onProtectDocument(typeProtection, password); - }}> - {Device.android && } - - - + - - { - setPassword(!isPassword); - }} /> + props.onProtectClick()} link="#"> + - {isPassword && - <> - - changePassword(e.target.value)} - className={isIos ? 'list-input-right' : ''} - /> - repeatPassword(e.target.value)} - className={isIos ? 'list-input-right' : ''} - /> - - -

If the password is forgotten or lost, it cannot be recovered.

-
- - } - {t('Settings.textTypeEditing')} - - { - appOptions.setTypeProtection(Asc.c_oAscEDocProtect.ReadOnly); - }}> - { - appOptions.setTypeProtection(Asc.c_oAscEDocProtect.Forms); - }}> - { - appOptions.setTypeProtection(Asc.c_oAscEDocProtect.TrackedChanges); - }}> - { - appOptions.setTypeProtection(Asc.c_oAscEDocProtect.Comments); - }}> - - -

Allow only this type of editing in the document.

-
) })); diff --git a/apps/documenteditor/mobile/src/view/settings/Settings.jsx b/apps/documenteditor/mobile/src/view/settings/Settings.jsx index d6cf9d98a6..1b45e799d6 100644 --- a/apps/documenteditor/mobile/src/view/settings/Settings.jsx +++ b/apps/documenteditor/mobile/src/view/settings/Settings.jsx @@ -4,7 +4,6 @@ import { useTranslation } from 'react-i18next'; import {f7} from 'framework7-react'; import { observer, inject } from "mobx-react"; import {Device} from '../../../../../common/mobile/utils/device'; - import DocumentSettingsController from "../../controller/settings/DocumentSettings"; import DocumentInfoController from "../../controller/settings/DocumentInfo"; import { DownloadController } from "../../controller/settings/Download"; @@ -14,6 +13,7 @@ import { MacrosSettings, Direction } from "./ApplicationSettings"; import About from '../../../../../common/mobile/lib/view/About'; import NavigationController from '../../controller/settings/Navigation'; import SharingSettings from "../../../../../common/mobile/lib/view/SharingSettings"; +import ProtectionDocumentController from '../../controller/settings/DocumentProtection'; import ProtectionController from '../../controller/settings/Protection'; const routes = [ @@ -79,8 +79,12 @@ const routes = [ // Protection { - path: '/protection-document/', + path: '/protection', component: ProtectionController + }, + { + path: '/protect', + component: ProtectionDocumentController } ]; @@ -155,8 +159,8 @@ const SettingsList = inject("storeAppOptions", "storeReview")(observer(props =>
} - - + + { if(Device.phone) { From 9f5273a5747ba9e939afa11e661cb9a5cc65c38b Mon Sep 17 00:00:00 2001 From: SergeyEzhin Date: Mon, 16 Jan 2023 14:44:57 +0400 Subject: [PATCH 3/9] [DE mobile] Add restrictions for protection modes --- apps/common/mobile/resources/less/common.less | 9 ++++++ apps/documenteditor/mobile/locale/en.json | 6 ++++ .../mobile/src/controller/ContextMenu.jsx | 28 +++++++++++-------- .../mobile/src/controller/Main.jsx | 18 ++++++++++-- .../settings/DocumentProtection.jsx | 12 ++++++-- .../src/controller/settings/Protection.jsx | 2 +- apps/documenteditor/mobile/src/page/main.jsx | 3 +- .../mobile/src/store/appOptions.js | 2 +- .../src/view/settings/DocumentProtection.jsx | 19 +++++++++++-- 9 files changed, 78 insertions(+), 21 deletions(-) diff --git a/apps/common/mobile/resources/less/common.less b/apps/common/mobile/resources/less/common.less index dc970e4267..aa23c23cae 100644 --- a/apps/common/mobile/resources/less/common.less +++ b/apps/common/mobile/resources/less/common.less @@ -1102,6 +1102,15 @@ input[type="number"]::-webkit-inner-spin-button { } } +// Block +.block { + margin-top: 8px; + font-style: normal; + font-weight: 400; + font-size: 12px; + line-height: 16px; +} + diff --git a/apps/documenteditor/mobile/locale/en.json b/apps/documenteditor/mobile/locale/en.json index b4c0904b85..07e4c97919 100644 --- a/apps/documenteditor/mobile/locale/en.json +++ b/apps/documenteditor/mobile/locale/en.json @@ -477,6 +477,11 @@ "errorUpdateVersion": "The file version has been changed. The page will be reloaded.", "leavePageText": "You have unsaved changes. Click 'Stay on this Page' to wait for autosave. Click 'Leave this Page' to discard all the unsaved changes.", "notcriticalErrorTitle": "Warning", + "titleDialogProtectedDocument": "The document is protected", + "textDialogProtectedOnlyView": "You may only view this document", + "textDialogProtectedFillForms": "You may only fill in forms in this document", + "textDialogProtectedChangesTracked": "You may edit this document, but all changes will be tracked", + "textDialogProtectedEditComments": "You may only insert comments to this document", "SDK": { " -Section ": " -Section ", "above": "above", @@ -673,6 +678,7 @@ "textVerify": "Verify", "textSave": "Save", "textRequired": "Required", + "textPasswordNotMatched": "Passwords Don’t Match", "textShowNotification": "Show Notification", "textSpaces": "Spaces", "textSpellcheck": "Spell Checking", diff --git a/apps/documenteditor/mobile/src/controller/ContextMenu.jsx b/apps/documenteditor/mobile/src/controller/ContextMenu.jsx index bf43216aa7..944adb2c57 100644 --- a/apps/documenteditor/mobile/src/controller/ContextMenu.jsx +++ b/apps/documenteditor/mobile/src/controller/ContextMenu.jsx @@ -21,12 +21,13 @@ import EditorUIController from '../lib/patch'; displayMode: stores.storeReview.displayMode, dataDoc: stores.storeDocumentInfo.dataDoc, objects: stores.storeFocusObjects.settings, - isViewer: stores.storeAppOptions.isViewer + isViewer: stores.storeAppOptions.isViewer, + isProtected: stores.storeAppOptions.isProtected, + typeProtection: stores.storeAppOptions.typeProtection })) class ContextMenu extends ContextMenuController { constructor(props) { super(props); - // console.log('context menu controller created'); this.onApiShowComment = this.onApiShowComment.bind(this); this.onApiHideComment = this.onApiHideComment.bind(this); @@ -283,13 +284,15 @@ class ContextMenu extends ContextMenuController { } else { const { t } = this.props; const _t = t("ContextMenu", {returnObjects: true}); - const { canViewComments, canCoAuthoring, canComments, dataDoc } = this.props; + const { canViewComments, canCoAuthoring, canComments, dataDoc, isProtected, typeProtection } = this.props; const api = Common.EditorApi.get(); const inToc = api.asc_GetTableOfContentsPr(true); const stack = api.getSelectedElements(); const canCopy = api.can_CopyCut(); const docExt = dataDoc ? dataDoc.fileType : ''; + const isAllowedEditing = !isProtected || typeProtection === Asc.c_oAscEDocProtect.TrackedChanges; + const isAllowedCommenting = typeProtection === Asc.c_oAscEDocProtect.Comments; let isText = false, isObject = false, @@ -325,14 +328,14 @@ class ContextMenu extends ContextMenuController { } if (!isDisconnected) { - if (canFillForms && canCopy && !locked && (!isViewer || docExt === 'oform')) { + if (canFillForms && canCopy && !locked && (!isViewer || docExt === 'oform') && isAllowedEditing) { itemsIcon.push({ event: 'cut', icon: 'icon-cut' }); } - if (canFillForms && canCopy && !locked && (!isViewer || docExt === 'oform')) { + if (canFillForms && canCopy && !locked && (!isViewer || docExt === 'oform') && isAllowedEditing) { itemsIcon.push({ event: 'paste', icon: 'icon-paste' @@ -346,7 +349,7 @@ class ContextMenu extends ContextMenuController { }); } - if (api.can_AddQuotedComment() !== false && canCoAuthoring && canComments && !locked && !(!isText && isObject) && !isViewer) { + if (api.can_AddQuotedComment() !== false && canCoAuthoring && canComments && !locked && !(!isText && isObject) && !isViewer && (isAllowedEditing || isAllowedCommenting)) { itemsText.push({ caption: _t.menuAddComment, event: 'addcomment' @@ -359,13 +362,16 @@ class ContextMenu extends ContextMenuController { caption: _t.menuOpenLink, event: 'openlink' }); - itemsText.push({ - caption: t('ContextMenu.menuEditLink'), - event: 'editlink' - }); + + if(isAllowedEditing) { + itemsText.push({ + caption: t('ContextMenu.menuEditLink'), + event: 'editlink' + }); + } } - if(inToc && isEdit && !isViewer) { + if(inToc && isEdit && !isViewer && isAllowedEditing) { itemsText.push({ caption: t('ContextMenu.textRefreshEntireTable'), event: 'refreshEntireTable' diff --git a/apps/documenteditor/mobile/src/controller/Main.jsx b/apps/documenteditor/mobile/src/controller/Main.jsx index 6deb76d39b..2630dfc775 100644 --- a/apps/documenteditor/mobile/src/controller/Main.jsx +++ b/apps/documenteditor/mobile/src/controller/Main.jsx @@ -794,6 +794,18 @@ class MainController extends Component { const storeAppOptions = this.props.storeAppOptions; const props = this.getDocProps(true); const isProtected = props && (props.isReadOnly || props.isCommentsOnly || props.isFormsOnly || props.isReviewOnly); + let textWarningDialog; + + switch(props.type) { + case Asc.c_oAscEDocProtect.ReadOnly: + textWarningDialog = t('Main.textDialogProtectedOnlyView') + case Asc.c_oAscEDocProtect.Comments: + textWarningDialog = t('Main.textDialogProtectedEditComments') + case Asc.c_oAscEDocProtect.TrackedChanges: + textWarningDialog = t('Main.textDialogProtectedChangesTracked') + case Asc.c_oAscEDocProtect.Forms: + textWarningDialog = t('Main.textDialogProtectedFillForms') + } storeAppOptions.setProtection(isProtected); props && this.applyRestrictions(props.type); @@ -801,8 +813,8 @@ class MainController extends Component { if(isProtected) { f7.dialog.create({ - title: t('Main.notcriticalErrorTitle'), - text: t('Main.textDocumentProtected'), + title: t('Main.titleDialogProtectedDocument'), + text: textWarningDialog, buttons: [ { text: t('Main.textOk') @@ -836,7 +848,7 @@ class MainController extends Component { if (!storeAppOptions || !storeAppOptions.isEdit && !storeAppOptions.isRestrictedEdit) return; - if (isUpdate || !this.state.docProtection) { + if (isUpdate || !this._state.docProtection) { const props = this.api.asc_getDocumentProtection(); const type = props ? props.asc_getEditType() : Asc.c_oAscEDocProtect.None; diff --git a/apps/documenteditor/mobile/src/controller/settings/DocumentProtection.jsx b/apps/documenteditor/mobile/src/controller/settings/DocumentProtection.jsx index 6f8bbef3d8..1a7743e453 100644 --- a/apps/documenteditor/mobile/src/controller/settings/DocumentProtection.jsx +++ b/apps/documenteditor/mobile/src/controller/settings/DocumentProtection.jsx @@ -1,6 +1,6 @@ import React from 'react'; import { Device } from '../../../../../common/mobile/utils/device'; -// import { withTranslation } from 'react-i18next'; +import { observer, inject } from "mobx-react"; import ProtectionDocumentView from '../../view/settings/DocumentProtection'; import { f7 } from "framework7-react"; @@ -20,8 +20,16 @@ class ProtectionDocumentController extends React.Component { onProtectDocument(typeProtection, password) { const api = Common.EditorApi.get(); + const appOptions = this.props.storeAppOptions; + const isViewer = appOptions.isViewer; const protection = api.asc_getDocumentProtection() || new AscCommonWord.CDocProtect(); + appOptions.setProtection(true); + + if(typeProtection !== Asc.c_oAscEDocProtect.TrackedChanges && !isViewer) { + appOptions.changeViewerMode(); + } + protection.asc_setEditType(typeProtection); protection.asc_setPassword(password); api.asc_setDocumentProtection(protection); @@ -34,4 +42,4 @@ class ProtectionDocumentController extends React.Component { } } -export default ProtectionDocumentController; \ No newline at end of file +export default inject('storeAppOptions')(observer(ProtectionDocumentController)); \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/controller/settings/Protection.jsx b/apps/documenteditor/mobile/src/controller/settings/Protection.jsx index e6ccec3abc..36f72d3edb 100644 --- a/apps/documenteditor/mobile/src/controller/settings/Protection.jsx +++ b/apps/documenteditor/mobile/src/controller/settings/Protection.jsx @@ -50,7 +50,7 @@ class ProtectionController extends React.Component { propsProtection = new AscCommonWord.CDocProtect(); propsProtection.asc_setEditType(Asc.c_oAscEDocProtect.None); - api.asc_setDocumentProtection(props); + api.asc_setDocumentProtection(propsProtection); } } else { f7.views.current.router.navigate('/protect'); diff --git a/apps/documenteditor/mobile/src/page/main.jsx b/apps/documenteditor/mobile/src/page/main.jsx index b49ecc209a..73b74965c4 100644 --- a/apps/documenteditor/mobile/src/page/main.jsx +++ b/apps/documenteditor/mobile/src/page/main.jsx @@ -134,7 +134,8 @@ class MainPage extends Component { const disabledControls = storeToolbarSettings.disabledControls; const disabledSettings = storeToolbarSettings.disabledSettings; const isProtected = appOptions.isProtected; - const isFabShow = isViewer && !disabledSettings && !disabledControls && !isDisconnected && isAvailableExt && isEdit && !isProtected; + const typeProtection = appOptions.typeProtection; + const isFabShow = isViewer && !disabledSettings && !disabledControls && !isDisconnected && isAvailableExt && isEdit && (!isProtected || typeProtection === Asc.c_oAscEDocProtect.TrackedChanges); const config = appOptions.config; let showLogo = !(config.customization && (config.customization.loaderName || config.customization.loaderLogo)); diff --git a/apps/documenteditor/mobile/src/store/appOptions.js b/apps/documenteditor/mobile/src/store/appOptions.js index 8516358004..29d1d9bc1a 100644 --- a/apps/documenteditor/mobile/src/store/appOptions.js +++ b/apps/documenteditor/mobile/src/store/appOptions.js @@ -46,7 +46,7 @@ export class storeAppOptions { this.isProtected = value; } - typeProtection = 3; + typeProtection; setTypeProtection(type) { this.typeProtection = type; } diff --git a/apps/documenteditor/mobile/src/view/settings/DocumentProtection.jsx b/apps/documenteditor/mobile/src/view/settings/DocumentProtection.jsx index 489250a5ee..ef0c274175 100644 --- a/apps/documenteditor/mobile/src/view/settings/DocumentProtection.jsx +++ b/apps/documenteditor/mobile/src/view/settings/DocumentProtection.jsx @@ -13,14 +13,29 @@ const ProtectionDocumentView = inject("storeAppOptions")(observer(props => { const [isPassword, setPassword] = useState(false); const [password, changePassword] = useState(''); const [passwordRepeat, repeatPassword] = useState(''); - const isDisabledProtection = isPassword && ((!password.length || !passwordRepeat.length) || password !== passwordRepeat); + const isDisabledProtection = isPassword && (!password.length || !passwordRepeat.length); + + const showErrorDialog = () => { + f7.dialog.create({ + title: t('Settings.textPasswordNotMatched'), + buttons: [ + { + text: t('Settings.textOk') + } + ] + }).open(); + }; return ( { - props.onProtectDocument(typeProtection, password); + if(password !== passwordRepeat) { + showErrorDialog(); + } else { + props.onProtectDocument(typeProtection, password); + } }}> {Device.android && } From 4eee959146113627e3b805ce798bb48a490809f4 Mon Sep 17 00:00:00 2001 From: SergeyEzhin Date: Tue, 17 Jan 2023 21:35:02 +0400 Subject: [PATCH 4/9] [DE mobile] Added restrictions for comments --- .../lib/view/collaboration/Comments.jsx | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/apps/common/mobile/lib/view/collaboration/Comments.jsx b/apps/common/mobile/lib/view/collaboration/Comments.jsx index 55d9a621fa..092e3c9215 100644 --- a/apps/common/mobile/lib/view/collaboration/Comments.jsx +++ b/apps/common/mobile/lib/view/collaboration/Comments.jsx @@ -642,6 +642,9 @@ const ViewComments = inject("storeComments", "storeAppOptions", "storeReview")(o const comments = storeComments.groupCollectionFilter || storeComments.collectionComments; const isEdit = storeAppOptions.isEdit || storeAppOptions.isRestrictedEdit; const sortComments = comments.length > 0 ? [...comments].sort((a, b) => a.time > b.time ? -1 : 1) : null; + const isProtected = storeAppOptions.isProtected; + const typeProtection = storeAppOptions.typeProtection; + const isAvailableCommenting = !isProtected || typeProtection === Asc.c_oAscEDocProtect.TrackedChanges || typeProtection === Asc.c_oAscEDocProtect.Comments; const [clickComment, setComment] = useState(); const [commentActionsOpened, openActionComment] = useState(false); @@ -678,8 +681,8 @@ const ViewComments = inject("storeComments", "storeAppOptions", "storeReview")(o {isEdit && !viewMode &&
- {(comment.editable && displayMode === 'markup' && !wsProps?.Objects && (!isViewer || canEditComments)) &&
{onResolveComment(comment);}}>
} - {(displayMode === 'markup' && !wsProps?.Objects && (!isViewer || canEditComments)) && + {(comment.editable && displayMode === 'markup' && !wsProps?.Objects && (!isViewer || canEditComments) && isAvailableCommenting) &&
{onResolveComment(comment);}}>
} + {(displayMode === 'markup' && !wsProps?.Objects && (!isViewer || canEditComments) && isAvailableCommenting) &&
{setComment(comment); openActionComment(true);}}> @@ -709,7 +712,7 @@ const ViewComments = inject("storeComments", "storeAppOptions", "storeReview")(o
{reply.date}
- {isEdit && !viewMode && reply.editable && (!isViewer || canEditComments) && + {isEdit && !viewMode && reply.editable && (!isViewer || canEditComments) && isAvailableCommenting &&
{setComment(comment); setReply(reply); openActionReply(true);}} @@ -753,6 +756,9 @@ const CommentList = inject("storeComments", "storeAppOptions", "storeReview")(ob const viewMode = !storeAppOptions.canComments; const isEdit = storeAppOptions.isEdit || storeAppOptions.isRestrictedEdit; const comments = storeComments.showComments; + const isProtected = storeAppOptions.isProtected; + const typeProtection = storeAppOptions.typeProtection; + const isAvailableCommenting = !isProtected || typeProtection === Asc.c_oAscEDocProtect.TrackedChanges || typeProtection === Asc.c_oAscEDocProtect.Comments; const [currentIndex, setCurrentIndex] = useState(0); const comment = comments[currentIndex]; @@ -789,7 +795,7 @@ const CommentList = inject("storeComments", "storeAppOptions", "storeReview")(ob {isEdit && !viewMode && - {onCommentMenuClick('addReply', comment);}}>{_t.textAddReply} + {onCommentMenuClick('addReply', comment);}}>{_t.textAddReply} }
@@ -809,15 +815,15 @@ const CommentList = inject("storeComments", "storeAppOptions", "storeReview")(ob
{isEdit && !viewMode && -
- {(comment.editable && displayMode === 'markup' && !wsProps?.Objects && (!isViewer || canEditComments)) &&
{onResolveComment(comment);}}>
} - {(displayMode === 'markup' && !wsProps?.Objects && (!isViewer || canEditComments)) && -
{openActionComment(true);}}> - -
- } -
+
+ {(comment.editable && displayMode === 'markup' && !wsProps?.Objects && (!isViewer || canEditComments) && isAvailableCommenting) &&
{onResolveComment(comment);}}>
} + {(displayMode === 'markup' && !wsProps?.Objects && (!isViewer || canEditComments) && isAvailableCommenting) && +
{openActionComment(true);}}> + +
+ } +
}
@@ -841,7 +847,7 @@ const CommentList = inject("storeComments", "storeAppOptions", "storeReview")(ob
{reply.date}
- {isEdit && !viewMode && reply.editable && (!isViewer || canEditComments) && + {isEdit && !viewMode && reply.editable && (!isViewer || canEditComments) && isAvailableCommenting &&
{setReply(reply); openActionReply(true);}} From ed8638ec13ebf2362fb2cd64c5df18575211b362 Mon Sep 17 00:00:00 2001 From: SergeyEzhin Date: Thu, 9 Feb 2023 21:48:09 +0400 Subject: [PATCH 5/9] [DE mobile] Add encryption file --- apps/documenteditor/mobile/locale/en.json | 3 + .../mobile/src/controller/Main.jsx | 5 +- .../controller/settings/FileEncryption.jsx | 50 +++++++++++ .../mobile/src/store/appOptions.js | 10 ++- .../src/view/settings/FileEncryption.jsx | 89 +++++++++++++++++++ .../mobile/src/view/settings/Protection.jsx | 3 + .../mobile/src/view/settings/Settings.jsx | 7 ++ 7 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 apps/documenteditor/mobile/src/controller/settings/FileEncryption.jsx create mode 100644 apps/documenteditor/mobile/src/view/settings/FileEncryption.jsx diff --git a/apps/documenteditor/mobile/locale/en.json b/apps/documenteditor/mobile/locale/en.json index 07e4c97919..7fda50a177 100644 --- a/apps/documenteditor/mobile/locale/en.json +++ b/apps/documenteditor/mobile/locale/en.json @@ -679,6 +679,9 @@ "textSave": "Save", "textRequired": "Required", "textPasswordNotMatched": "Passwords Don’t Match", + "textEncryptFile": "Encrypt File", + "textRequirePassword": "Require Password", + "textChangePassword": "Change Password", "textShowNotification": "Show Notification", "textSpaces": "Spaces", "textSpellcheck": "Spell Checking", diff --git a/apps/documenteditor/mobile/src/controller/Main.jsx b/apps/documenteditor/mobile/src/controller/Main.jsx index 2630dfc775..8100e5426e 100644 --- a/apps/documenteditor/mobile/src/controller/Main.jsx +++ b/apps/documenteditor/mobile/src/controller/Main.jsx @@ -756,9 +756,12 @@ class MainController extends Component { // Downloaded Advanced Options this.api.asc_registerCallback('asc_onAdvancedOptions', (type, advOptions, mode, formatOptions) => { - const {t} = this.props; + const { t } = this.props; const _t = t("Settings", { returnObjects: true }); + const storeAppOptions = this.props.storeAppOptions; + if(type == Asc.c_oAscAdvancedOptionsID.DRM) { + storeAppOptions.setEncryptionFile(true); onAdvancedOptions(type, _t, this._isDocReady, this.props.storeAppOptions.canRequestClose, this.isDRM); this.isDRM = true; } diff --git a/apps/documenteditor/mobile/src/controller/settings/FileEncryption.jsx b/apps/documenteditor/mobile/src/controller/settings/FileEncryption.jsx new file mode 100644 index 0000000000..ae80c5b4bb --- /dev/null +++ b/apps/documenteditor/mobile/src/controller/settings/FileEncryption.jsx @@ -0,0 +1,50 @@ +import React from 'react'; +import { observer, inject } from "mobx-react"; +import EncryptionView from '../../view/settings/FileEncryption'; +import { withTranslation } from 'react-i18next'; +import { f7 } from "framework7-react"; +import { Device } from '../../../../../common/mobile/utils/device'; + +class FileEncryptionController extends React.Component { + constructor(props) { + super(props); + + this.deletePassword = this.deletePassword.bind(this); + this.setPassword = this.setPassword.bind(this); + } + + closeModal() { + if (Device.phone) { + f7.sheet.close('.settings-popup', false); + } else { + f7.popover.close('#settings-popover', false); + } + } + + setPassword(passwordValue) { + const api = Common.EditorApi.get(); + + api.asc_setCurrentPassword(passwordValue); + this.closeModal(); + } + + deletePassword() { + const api = Common.EditorApi.get(); + const appOptions = this.props.storeAppOptions; + + appOptions.setEncryptionFile(false); + api.asc_resetPassword(); + this.closeModal(); + } + + render() { + return ( + + ) + } +} + +export default inject('storeAppOptions')(observer(withTranslation()(FileEncryptionController))); \ 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 29d1d9bc1a..d633d96fd7 100644 --- a/apps/documenteditor/mobile/src/store/appOptions.js +++ b/apps/documenteditor/mobile/src/store/appOptions.js @@ -35,12 +35,20 @@ export class storeAppOptions { setProtection: action, typeProtection: observable, - setTypeProtection: action + setTypeProtection: action, + + isFileEncrypted: observable, + setEncryptionFile: action }); } isEdit = false; + isFileEncrypted = false; + setEncryptionFile(value) { + this.isFileEncrypted = value; + } + isProtected = false; setProtection(value) { this.isProtected = value; diff --git a/apps/documenteditor/mobile/src/view/settings/FileEncryption.jsx b/apps/documenteditor/mobile/src/view/settings/FileEncryption.jsx new file mode 100644 index 0000000000..947cb1c44f --- /dev/null +++ b/apps/documenteditor/mobile/src/view/settings/FileEncryption.jsx @@ -0,0 +1,89 @@ +import React, { useState } from 'react'; +import { observer, inject } from "mobx-react"; +import { Device } from '../../../../../common/mobile/utils/device'; +import { Page, Navbar, List, ListItem, BlockTitle, Toggle, NavRight, f7, Link, ListInput, Icon, Block } from "framework7-react"; +import { useTranslation } from "react-i18next"; + +const EncryptionView = inject("storeAppOptions")(observer(props => { + const { t } = useTranslation(); + const _t = t("Settings", { returnObjects: true }); + const isIos = Device.ios; + const appOptions = props.storeAppOptions; + const isFileEncrypted = appOptions.isFileEncrypted; + const [isRequiredPassword, setRequirePassword] = useState(isFileEncrypted); + const [password, changePassword] = useState(''); + const [passwordRepeat, repeatPassword] = useState(''); + const isDisabledEncryption = isFileEncrypted && !isRequiredPassword ? false : !password.length || !passwordRepeat.length; + + const showErrorDialog = () => { + f7.dialog.create({ + title: t('Settings.textPasswordNotMatched'), + buttons: [ + { + text: t('Settings.textOk') + } + ] + }).open(); + }; + + const changeHanlder = () => { + if(isFileEncrypted && !isRequiredPassword) { + props.deletePassword(); + } else if(password !== passwordRepeat) { + showErrorDialog(); + } else { + props.setPassword(password); + } + } + + return ( + + + + + {Device.android && } + + + + {isFileEncrypted && + <> + + + { + setRequirePassword(!isRequiredPassword); + }} /> + + + + } + {(isFileEncrypted && isRequiredPassword || !isFileEncrypted) && + <> + {t('Settings.textChangePassword')} + + changePassword(e.target.value)} + className={isIos ? 'list-input-right' : ''} + /> + repeatPassword(e.target.value)} + className={isIos ? 'list-input-right' : ''} + /> + + +

If the password is forgotten or lost, it cannot be recovered.

+
+ + } +
+ ) +})); + +export default EncryptionView; \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/view/settings/Protection.jsx b/apps/documenteditor/mobile/src/view/settings/Protection.jsx index 02c3749e4e..2c08af3d52 100644 --- a/apps/documenteditor/mobile/src/view/settings/Protection.jsx +++ b/apps/documenteditor/mobile/src/view/settings/Protection.jsx @@ -16,6 +16,9 @@ const ProtectionView = inject("storeAppOptions")(observer(props => { props.onProtectClick()} link="#"> + + + ) diff --git a/apps/documenteditor/mobile/src/view/settings/Settings.jsx b/apps/documenteditor/mobile/src/view/settings/Settings.jsx index 1b45e799d6..99064ac597 100644 --- a/apps/documenteditor/mobile/src/view/settings/Settings.jsx +++ b/apps/documenteditor/mobile/src/view/settings/Settings.jsx @@ -15,6 +15,7 @@ import NavigationController from '../../controller/settings/Navigation'; import SharingSettings from "../../../../../common/mobile/lib/view/SharingSettings"; import ProtectionDocumentController from '../../controller/settings/DocumentProtection'; import ProtectionController from '../../controller/settings/Protection'; +import FileEncryptionController from '../../controller/settings/FileEncryption'; const routes = [ { @@ -85,6 +86,12 @@ const routes = [ { path: '/protect', component: ProtectionDocumentController + }, + + // Encryption + { + path: '/encrypt', + component: FileEncryptionController } ]; From 08387cfc4c69c030b35124b52dc51cd39ac165b2 Mon Sep 17 00:00:00 2001 From: SergeyEzhin Date: Sun, 12 Feb 2023 21:07:18 +0400 Subject: [PATCH 6/9] [DE mobile] Correct protection and encryption --- .../mobile/resources/less/comments.less | 2 +- apps/common/mobile/resources/less/common.less | 5 +- .../mobile/src/controller/Main.jsx | 12 +++-- .../settings/DocumentProtection.jsx | 1 + .../src/controller/settings/Protection.jsx | 1 + .../src/controller/settings/Settings.jsx | 50 ++++++++++++++++++- .../mobile/src/store/appOptions.js | 2 +- .../src/view/settings/DocumentProtection.jsx | 49 ++++++++++-------- .../src/view/settings/FileEncryption.jsx | 4 +- .../mobile/src/view/settings/Settings.jsx | 19 +++++-- 10 files changed, 109 insertions(+), 36 deletions(-) diff --git a/apps/common/mobile/resources/less/comments.less b/apps/common/mobile/resources/less/comments.less index d74217ad02..38aa914e0e 100644 --- a/apps/common/mobile/resources/less/comments.less +++ b/apps/common/mobile/resources/less/comments.less @@ -233,7 +233,7 @@ overflow: auto; .item-content .item-input-wrap::after { - background-color: @text-normal; + background-color: @brandColor; } } diff --git a/apps/common/mobile/resources/less/common.less b/apps/common/mobile/resources/less/common.less index aa23c23cae..0fef8ea349 100644 --- a/apps/common/mobile/resources/less/common.less +++ b/apps/common/mobile/resources/less/common.less @@ -1111,7 +1111,10 @@ input[type="number"]::-webkit-inner-spin-button { line-height: 16px; } - +// Inputs List +.block-title + .list, .block-title + .block, .block-title + .card, .block-title + .timeline, .block-title + .block-header { + margin: 0; +} diff --git a/apps/documenteditor/mobile/src/controller/Main.jsx b/apps/documenteditor/mobile/src/controller/Main.jsx index 8100e5426e..40d6c4b376 100644 --- a/apps/documenteditor/mobile/src/controller/Main.jsx +++ b/apps/documenteditor/mobile/src/controller/Main.jsx @@ -800,14 +800,18 @@ class MainController extends Component { let textWarningDialog; switch(props.type) { - case Asc.c_oAscEDocProtect.ReadOnly: - textWarningDialog = t('Main.textDialogProtectedOnlyView') + case Asc.c_oAscEDocProtect.ReadOnly: + textWarningDialog = t('Main.textDialogProtectedOnlyView'); + break; case Asc.c_oAscEDocProtect.Comments: - textWarningDialog = t('Main.textDialogProtectedEditComments') + textWarningDialog = t('Main.textDialogProtectedEditComments'); + break; case Asc.c_oAscEDocProtect.TrackedChanges: textWarningDialog = t('Main.textDialogProtectedChangesTracked') + break; case Asc.c_oAscEDocProtect.Forms: - textWarningDialog = t('Main.textDialogProtectedFillForms') + textWarningDialog = t('Main.textDialogProtectedFillForms'); + break; } storeAppOptions.setProtection(isProtected); diff --git a/apps/documenteditor/mobile/src/controller/settings/DocumentProtection.jsx b/apps/documenteditor/mobile/src/controller/settings/DocumentProtection.jsx index 1a7743e453..2fd08ed41d 100644 --- a/apps/documenteditor/mobile/src/controller/settings/DocumentProtection.jsx +++ b/apps/documenteditor/mobile/src/controller/settings/DocumentProtection.jsx @@ -25,6 +25,7 @@ class ProtectionDocumentController extends React.Component { const protection = api.asc_getDocumentProtection() || new AscCommonWord.CDocProtect(); appOptions.setProtection(true); + appOptions.setTypeProtection(typeProtection); if(typeProtection !== Asc.c_oAscEDocProtect.TrackedChanges && !isViewer) { appOptions.changeViewerMode(); diff --git a/apps/documenteditor/mobile/src/controller/settings/Protection.jsx b/apps/documenteditor/mobile/src/controller/settings/Protection.jsx index 36f72d3edb..cf95904e25 100644 --- a/apps/documenteditor/mobile/src/controller/settings/Protection.jsx +++ b/apps/documenteditor/mobile/src/controller/settings/Protection.jsx @@ -49,6 +49,7 @@ class ProtectionController extends React.Component { if (!propsProtection) propsProtection = new AscCommonWord.CDocProtect(); + appOptions.setTypeProtection(null); propsProtection.asc_setEditType(Asc.c_oAscEDocProtect.None); api.asc_setDocumentProtection(propsProtection); } diff --git a/apps/documenteditor/mobile/src/controller/settings/Settings.jsx b/apps/documenteditor/mobile/src/controller/settings/Settings.jsx index 8a319d35b6..eac911dbab 100644 --- a/apps/documenteditor/mobile/src/controller/settings/Settings.jsx +++ b/apps/documenteditor/mobile/src/controller/settings/Settings.jsx @@ -3,11 +3,12 @@ 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"; import {LocalStorage} from "../../../../../common/mobile/utils/LocalStorage.mjs"; const Settings = props => { + const { t } = useTranslation(); + useEffect(() => { if ( Device.phone ) { f7.popup.open('.settings-popup'); @@ -92,6 +93,52 @@ const Settings = props => { api.ChangeReaderMode(); }; + const onProtectClick = () => { + const api = Common.EditorApi.get(); + const appOptions = props.storeAppOptions; + const isProtected = appOptions.isProtected; + let propsProtection = api.asc_getDocumentProtection(); + const isPassword = propsProtection?.asc_getIsPassword(); + + if(isProtected) { + if(propsProtection && isPassword) { + f7.dialog.create({ + title: t('Settings.titleDialogUnprotect'), + text: t('Settings.textDialogUnprotect'), + content: Device.ios ? + '
' : '
', + cssClass: 'dlg-adv-options', + buttons: [ + { + text: t('Settings.textCancel') + }, + { + text: t('Settings.textOk'), + onClick: () => { + const passwordValue = document.querySelector('#protection-password')?.value; + + if(passwordValue) { + propsProtection.asc_setEditType(Asc.c_oAscEDocProtect.None); + propsProtection.asc_setPassword(passwordValue); + api.asc_setDocumentProtection(propsProtection); + } + } + } + ] + }).open(); + } else { + if (!propsProtection) + propsProtection = new AscCommonWord.CDocProtect(); + + appOptions.setTypeProtection(null); + propsProtection.asc_setEditType(Asc.c_oAscEDocProtect.None); + api.asc_setDocumentProtection(propsProtection); + } + } else { + f7.views.current.router.navigate('/protect'); + } + } + return { onOrthographyCheck={onOrthographyCheck} onDownloadOrigin={onDownloadOrigin} onChangeMobileView={onChangeMobileView} + onProtectClick={onProtectClick} /> }; diff --git a/apps/documenteditor/mobile/src/store/appOptions.js b/apps/documenteditor/mobile/src/store/appOptions.js index d633d96fd7..5dd0e887a0 100644 --- a/apps/documenteditor/mobile/src/store/appOptions.js +++ b/apps/documenteditor/mobile/src/store/appOptions.js @@ -54,7 +54,7 @@ export class storeAppOptions { this.isProtected = value; } - typeProtection; + typeProtection = null; setTypeProtection(type) { this.typeProtection = type; } diff --git a/apps/documenteditor/mobile/src/view/settings/DocumentProtection.jsx b/apps/documenteditor/mobile/src/view/settings/DocumentProtection.jsx index ef0c274175..8e6a4d7bf0 100644 --- a/apps/documenteditor/mobile/src/view/settings/DocumentProtection.jsx +++ b/apps/documenteditor/mobile/src/view/settings/DocumentProtection.jsx @@ -10,10 +10,11 @@ const ProtectionDocumentView = inject("storeAppOptions")(observer(props => { const isIos = Device.ios; const appOptions = props.storeAppOptions; const typeProtection = appOptions.typeProtection; - const [isPassword, setPassword] = useState(false); + const [stateTypeProtection, setStateTypeProtection] = useState(typeProtection); + const [isRequirePassword, setRequirePassword] = useState(false); const [password, changePassword] = useState(''); - const [passwordRepeat, repeatPassword] = useState(''); - const isDisabledProtection = isPassword && (!password.length || !passwordRepeat.length); + const [passwordRepeat, changeRepeationPassword] = useState(''); + const isDisabledProtection = isRequirePassword ? ((!password.length || !passwordRepeat.length) || stateTypeProtection === null) : stateTypeProtection === null; const showErrorDialog = () => { f7.dialog.create({ @@ -26,29 +27,33 @@ const ProtectionDocumentView = inject("storeAppOptions")(observer(props => { }).open(); }; + const changeHanlder = () => { + if(isRequirePassword && password !== passwordRepeat) { + showErrorDialog(); + } else { + props.onProtectDocument(stateTypeProtection, password); + } + } + return ( - { - if(password !== passwordRepeat) { - showErrorDialog(); - } else { - props.onProtectDocument(typeProtection, password); - } - }}> + {Device.android && } - { - setPassword(!isPassword); + { + setRequirePassword(!isRequirePassword); + changePassword(''); + changeRepeationPassword(''); }} /> - {isPassword && + {isRequirePassword && <> { type="password" placeholder={t('Settings.textRequired')} value={passwordRepeat} - onInput={e => repeatPassword(e.target.value)} + onInput={e => changeRepeationPassword(e.target.value)} className={isIos ? 'list-input-right' : ''} /> @@ -75,17 +80,17 @@ const ProtectionDocumentView = inject("storeAppOptions")(observer(props => { } {t('Settings.textTypeEditing')} - { - appOptions.setTypeProtection(Asc.c_oAscEDocProtect.ReadOnly); + { + setStateTypeProtection(Asc.c_oAscEDocProtect.ReadOnly); }}> - { - appOptions.setTypeProtection(Asc.c_oAscEDocProtect.Forms); + { + setStateTypeProtection(Asc.c_oAscEDocProtect.Forms); }}> - { - appOptions.setTypeProtection(Asc.c_oAscEDocProtect.TrackedChanges); + { + setStateTypeProtection(Asc.c_oAscEDocProtect.TrackedChanges); }}> - { - appOptions.setTypeProtection(Asc.c_oAscEDocProtect.Comments); + { + setStateTypeProtection(Asc.c_oAscEDocProtect.Comments); }}> diff --git a/apps/documenteditor/mobile/src/view/settings/FileEncryption.jsx b/apps/documenteditor/mobile/src/view/settings/FileEncryption.jsx index 947cb1c44f..afe88bafb0 100644 --- a/apps/documenteditor/mobile/src/view/settings/FileEncryption.jsx +++ b/apps/documenteditor/mobile/src/view/settings/FileEncryption.jsx @@ -56,9 +56,11 @@ const EncryptionView = inject("storeAppOptions")(observer(props => { } + {isFileEncrypted && isRequiredPassword && + {t('Settings.textChangePassword')} + } {(isFileEncrypted && isRequiredPassword || !isFileEncrypted) && <> - {t('Settings.textChangePassword')} // set mode const isViewer = appOptions.isViewer; const isMobileView = appOptions.isMobileView; + const isProtected = appOptions.isProtected; let _isEdit = false, _canDownload = false, @@ -166,9 +167,16 @@ const SettingsList = inject("storeAppOptions", "storeReview")(observer(props => } - - - + {_isEdit && !isViewer && + + + + } + {_isEdit && isViewer && + props.onProtectClick()} link="#"> + + + } { if(Device.phone) { onOpenNavigation(); @@ -257,13 +265,14 @@ class SettingsView extends Component { render() { const show_popover = this.props.usePopover; + return ( show_popover ? this.props.closeOptions('settings')}> - + : this.props.closeOptions('settings')}> - + ) } From 0444e6bf85c4a7bf452c83c303f8d22040d26e41 Mon Sep 17 00:00:00 2001 From: SergeyEzhin Date: Tue, 14 Feb 2023 11:09:23 +0400 Subject: [PATCH 7/9] [DE mobile] Corrected styles and snackbar --- .../mobile/resources/less/common-ios.less | 2 ++ .../resources/less/common-material.less | 2 ++ apps/common/mobile/resources/less/common.less | 4 +++ apps/documenteditor/mobile/locale/en.json | 1 + .../src/components/Snackbar/Snackbar.jsx | 26 +++++++++++---- .../src/controller/settings/Protection.jsx | 32 +++++++++++-------- .../mobile/src/less/app-ios.less | 2 +- .../mobile/src/less/app-material.less | 1 - apps/documenteditor/mobile/src/page/main.jsx | 25 ++++----------- 9 files changed, 55 insertions(+), 40 deletions(-) diff --git a/apps/common/mobile/resources/less/common-ios.less b/apps/common/mobile/resources/less/common-ios.less index ff36bcc827..a05e22b5c5 100644 --- a/apps/common/mobile/resources/less/common-ios.less +++ b/apps/common/mobile/resources/less/common-ios.less @@ -55,6 +55,8 @@ --f7-picker-item-text-color: rgba(var(--text-normal), 0.45); --f7-picker-item-selected-text-color: @text-normal; + --f7-block-text-color: @text-secondary; + // Main Toolbar #editor-navbar.navbar .right a + a, #editor-navbar.navbar .left a + a { diff --git a/apps/common/mobile/resources/less/common-material.less b/apps/common/mobile/resources/less/common-material.less index 570d532854..61fd561d7b 100644 --- a/apps/common/mobile/resources/less/common-material.less +++ b/apps/common/mobile/resources/less/common-material.less @@ -50,6 +50,8 @@ --f7-input-bg-color: @background-primary; --f7-input-placeholder-color: @text-secondary; --f7-input-text-color: @text-normal; + + --f7-block-text-color: @text-secondary; .button { --f7-touch-ripple-color: transparent; diff --git a/apps/common/mobile/resources/less/common.less b/apps/common/mobile/resources/less/common.less index 0fef8ea349..e088c554b2 100644 --- a/apps/common/mobile/resources/less/common.less +++ b/apps/common/mobile/resources/less/common.less @@ -1116,6 +1116,10 @@ input[type="number"]::-webkit-inner-spin-button { margin: 0; } +.inputs-list { + margin-bottom: 0; +} + diff --git a/apps/documenteditor/mobile/locale/en.json b/apps/documenteditor/mobile/locale/en.json index 7fda50a177..1c4c004a96 100644 --- a/apps/documenteditor/mobile/locale/en.json +++ b/apps/documenteditor/mobile/locale/en.json @@ -669,6 +669,7 @@ "titleDialogUnprotect": "Unprotect Document", "textDialogUnprotect": "Enter a password to unprotect document", "textUnprotect": "Unprotect", + "textProtectTurnOff": "Protect turn off", "textSetPassword": "Set Password", "textTypeEditing": "Type Of Editing", "textNoChanges": "No changes (Read only)", diff --git a/apps/documenteditor/mobile/src/components/Snackbar/Snackbar.jsx b/apps/documenteditor/mobile/src/components/Snackbar/Snackbar.jsx index ae94a2109a..28c65f6db6 100644 --- a/apps/documenteditor/mobile/src/components/Snackbar/Snackbar.jsx +++ b/apps/documenteditor/mobile/src/components/Snackbar/Snackbar.jsx @@ -1,13 +1,27 @@ import React from 'react'; +import { CSSTransition } from "react-transition-group"; -const Snackbar = props => { +const Snackbar = ({ isShowSnackbar, message, closeCallback }) => { return ( -
-
-

{props.text}

+ { + if(!isAppearing) { + closeCallback(); + } + }} + > +
+
+

{message}

+
-
- ) + + ); } export default Snackbar; \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/controller/settings/Protection.jsx b/apps/documenteditor/mobile/src/controller/settings/Protection.jsx index cf95904e25..f6a5ad2cf2 100644 --- a/apps/documenteditor/mobile/src/controller/settings/Protection.jsx +++ b/apps/documenteditor/mobile/src/controller/settings/Protection.jsx @@ -1,20 +1,18 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { observer, inject } from "mobx-react"; import ProtectionView from '../../view/settings/Protection'; -import { withTranslation } from 'react-i18next'; +import { useTranslation } from 'react-i18next'; import { f7 } from "framework7-react"; import { Device } from '../../../../../common/mobile/utils/device'; +import Snackbar from '../../components/Snackbar/Snackbar'; -class ProtectionController extends React.Component { - constructor(props) { - super(props); - this.onProtectClick = this.onProtectClick.bind(this); - } +const ProtectionController = props => { + const { t } = useTranslation(); + const [isSnackbarVisible, setSnackbarVisible] = useState(false); - onProtectClick() { + const onProtectClick = () => { const api = Common.EditorApi.get(); - const { t } = this.props; - const appOptions = this.props.storeAppOptions; + const appOptions = props.storeAppOptions; const isProtected = appOptions.isProtected; let propsProtection = api.asc_getDocumentProtection(); const isPassword = propsProtection?.asc_getIsPassword(); @@ -52,15 +50,21 @@ class ProtectionController extends React.Component { appOptions.setTypeProtection(null); propsProtection.asc_setEditType(Asc.c_oAscEDocProtect.None); api.asc_setDocumentProtection(propsProtection); + + setSnackbarVisible(true); } } else { f7.views.current.router.navigate('/protect'); } } - render() { - return - } + return ( + <> + + setSnackbarVisible(false)} /> + + ); + } -export default inject('storeAppOptions')(observer(withTranslation()(ProtectionController))); \ No newline at end of file +export default inject('storeAppOptions')(observer(ProtectionController)); \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/less/app-ios.less b/apps/documenteditor/mobile/src/less/app-ios.less index a30272e5a8..be54f83121 100644 --- a/apps/documenteditor/mobile/src/less/app-ios.less +++ b/apps/documenteditor/mobile/src/less/app-ios.less @@ -60,7 +60,7 @@ // Snackbar .snackbar { - max-width: 195px; + width: 195px; position: absolute; bottom: 24px; left: calc(50% - 195px / 2); diff --git a/apps/documenteditor/mobile/src/less/app-material.less b/apps/documenteditor/mobile/src/less/app-material.less index da45b41bd9..8b89dc0edc 100644 --- a/apps/documenteditor/mobile/src/less/app-material.less +++ b/apps/documenteditor/mobile/src/less/app-material.less @@ -110,7 +110,6 @@ .snackbar { position: absolute; width: 344px; - max-height: 48px; left: calc(50% - 344px / 2); bottom: 16px; background: #333333; diff --git a/apps/documenteditor/mobile/src/page/main.jsx b/apps/documenteditor/mobile/src/page/main.jsx index 73b74965c4..2e1c58dd76 100644 --- a/apps/documenteditor/mobile/src/page/main.jsx +++ b/apps/documenteditor/mobile/src/page/main.jsx @@ -15,7 +15,7 @@ import { Toolbar } from "../controller/Toolbar"; import NavigationController from '../controller/settings/Navigation'; import { AddLinkController } from '../controller/add/AddLink'; import EditHyperlink from '../controller/edit/EditHyperlink'; -import Snackbar from "../components/Snackbar/Snackbar"; +import Snackbar from '../components/Snackbar/Snackbar'; class MainPage extends Component { constructor(props) { @@ -198,23 +198,12 @@ class MainPage extends Component { {/* { Device.phone ? null : } */} - { - if(!isAppearing) { - this.setState({ - snackbarVisible: false - }); - } - }} - > - - + + this.handleOptionsViewClosed('snackbar')} + message={isMobileView ? t("Toolbar.textSwitchedMobileView") : t("Toolbar.textSwitchedStandardView")} + /> { !this.state.editOptionsVisible ? null : From d693a483e27a9d93ae86b1b640591ed7c3099d52 Mon Sep 17 00:00:00 2001 From: SergeyEzhin Date: Tue, 14 Feb 2023 23:17:35 +0400 Subject: [PATCH 8/9] [DE mobile] Correct protection settings --- apps/common/mobile/resources/less/common.less | 8 +++ .../mobile/resources/less/material/icons.less | 10 ++++ .../FieldPassword/FieldPassword.jsx | 28 +++++++++++ .../src/controller/settings/Settings.jsx | 49 ------------------- .../src/view/settings/DocumentProtection.jsx | 45 ++++++++++------- .../mobile/src/view/settings/Settings.jsx | 12 ++--- 6 files changed, 76 insertions(+), 76 deletions(-) create mode 100644 apps/documenteditor/mobile/src/components/FieldPassword/FieldPassword.jsx diff --git a/apps/common/mobile/resources/less/common.less b/apps/common/mobile/resources/less/common.less index e088c554b2..a51fd32727 100644 --- a/apps/common/mobile/resources/less/common.less +++ b/apps/common/mobile/resources/less/common.less @@ -1118,6 +1118,14 @@ input[type="number"]::-webkit-inner-spin-button { .inputs-list { margin-bottom: 0; + + ul { + list-style: none; + margin: 0; + padding: 0; + position: relative; + background: var(--f7-list-bg-color); + } } diff --git a/apps/common/mobile/resources/less/material/icons.less b/apps/common/mobile/resources/less/material/icons.less index 914e15bc34..f02091cc24 100644 --- a/apps/common/mobile/resources/less/material/icons.less +++ b/apps/common/mobile/resources/less/material/icons.less @@ -26,6 +26,16 @@ display: none; } } + &.icon-show-password { + width: 24px; + height: 24px; + .encoded-svg-mask('', @text-secondary); + } + &.icon-hide-password { + width: 24px; + height: 24px; + .encoded-svg-mask('', @text-secondary); + } } .navbar { i.icon { diff --git a/apps/documenteditor/mobile/src/components/FieldPassword/FieldPassword.jsx b/apps/documenteditor/mobile/src/components/FieldPassword/FieldPassword.jsx new file mode 100644 index 0000000000..8f40790944 --- /dev/null +++ b/apps/documenteditor/mobile/src/components/FieldPassword/FieldPassword.jsx @@ -0,0 +1,28 @@ +import React, { useState } from 'react'; +import { ListInput, Icon } from "framework7-react"; +import { Device } from '../../../../../common/mobile/utils/device'; + +const FieldPassword = ({ label, value, onInput, placeholder }) => { + const isIos = Device.ios; + const [isShowPassword, setShowPassword] = useState(false); + + const toggleShowPassword = () => { + setShowPassword(!isShowPassword); + }; + + return ( + + {/* */} + + ); +} + +export default FieldPassword; \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/controller/settings/Settings.jsx b/apps/documenteditor/mobile/src/controller/settings/Settings.jsx index eac911dbab..d2f03cd158 100644 --- a/apps/documenteditor/mobile/src/controller/settings/Settings.jsx +++ b/apps/documenteditor/mobile/src/controller/settings/Settings.jsx @@ -7,8 +7,6 @@ import SettingsView from "../../view/settings/Settings"; import {LocalStorage} from "../../../../../common/mobile/utils/LocalStorage.mjs"; const Settings = props => { - const { t } = useTranslation(); - useEffect(() => { if ( Device.phone ) { f7.popup.open('.settings-popup'); @@ -93,52 +91,6 @@ const Settings = props => { api.ChangeReaderMode(); }; - const onProtectClick = () => { - const api = Common.EditorApi.get(); - const appOptions = props.storeAppOptions; - const isProtected = appOptions.isProtected; - let propsProtection = api.asc_getDocumentProtection(); - const isPassword = propsProtection?.asc_getIsPassword(); - - if(isProtected) { - if(propsProtection && isPassword) { - f7.dialog.create({ - title: t('Settings.titleDialogUnprotect'), - text: t('Settings.textDialogUnprotect'), - content: Device.ios ? - '
' : '
', - cssClass: 'dlg-adv-options', - buttons: [ - { - text: t('Settings.textCancel') - }, - { - text: t('Settings.textOk'), - onClick: () => { - const passwordValue = document.querySelector('#protection-password')?.value; - - if(passwordValue) { - propsProtection.asc_setEditType(Asc.c_oAscEDocProtect.None); - propsProtection.asc_setPassword(passwordValue); - api.asc_setDocumentProtection(propsProtection); - } - } - } - ] - }).open(); - } else { - if (!propsProtection) - propsProtection = new AscCommonWord.CDocProtect(); - - appOptions.setTypeProtection(null); - propsProtection.asc_setEditType(Asc.c_oAscEDocProtect.None); - api.asc_setDocumentProtection(propsProtection); - } - } else { - f7.views.current.router.navigate('/protect'); - } - } - return { onOrthographyCheck={onOrthographyCheck} onDownloadOrigin={onDownloadOrigin} onChangeMobileView={onChangeMobileView} - onProtectClick={onProtectClick} /> }; diff --git a/apps/documenteditor/mobile/src/view/settings/DocumentProtection.jsx b/apps/documenteditor/mobile/src/view/settings/DocumentProtection.jsx index 8e6a4d7bf0..7769c0d62a 100644 --- a/apps/documenteditor/mobile/src/view/settings/DocumentProtection.jsx +++ b/apps/documenteditor/mobile/src/view/settings/DocumentProtection.jsx @@ -3,6 +3,7 @@ import { observer, inject } from "mobx-react"; import { Device } from '../../../../../common/mobile/utils/device'; import { Page, Navbar, List, ListItem, BlockTitle, Toggle, NavRight, f7, Link, ListInput, Icon, Block } from "framework7-react"; import { useTranslation } from "react-i18next"; +import FieldPassword from '../../components/FieldPassword/FieldPassword'; const ProtectionDocumentView = inject("storeAppOptions")(observer(props => { const { t } = useTranslation(); @@ -53,26 +54,34 @@ const ProtectionDocumentView = inject("storeAppOptions")(observer(props => { }} /> + {isRequirePassword && <> - - changePassword(e.target.value)} - className={isIos ? 'list-input-right' : ''} - /> - changeRepeationPassword(e.target.value)} - className={isIos ? 'list-input-right' : ''} - /> - + {Device.android ? + + changePassword(e.target.value)} /> + changeRepeationPassword(e.target.value)} /> + + : + + changePassword(e.target.value)} + className={isIos ? 'list-input-right' : ''} + /> + changeRepeationPassword(e.target.value)} + className={isIos ? 'list-input-right' : ''} + /> + + }

If the password is forgotten or lost, it cannot be recovered.

diff --git a/apps/documenteditor/mobile/src/view/settings/Settings.jsx b/apps/documenteditor/mobile/src/view/settings/Settings.jsx index 41fc5c07db..795f30e9bb 100644 --- a/apps/documenteditor/mobile/src/view/settings/Settings.jsx +++ b/apps/documenteditor/mobile/src/view/settings/Settings.jsx @@ -132,7 +132,6 @@ const SettingsList = inject("storeAppOptions", "storeReview")(observer(props => // set mode const isViewer = appOptions.isViewer; const isMobileView = appOptions.isMobileView; - const isProtected = appOptions.isProtected; let _isEdit = false, _canDownload = false, @@ -167,16 +166,11 @@ const SettingsList = inject("storeAppOptions", "storeReview")(observer(props => } - {_isEdit && !isViewer && + {_isEdit && } - {_isEdit && isViewer && - props.onProtectClick()} link="#"> - - - } { if(Device.phone) { onOpenNavigation(); @@ -269,10 +263,10 @@ class SettingsView extends Component { return ( show_popover ? this.props.closeOptions('settings')}> - + : this.props.closeOptions('settings')}> - + ) } From eafeb56e90a227c40507b5dc7823cb695b46207c Mon Sep 17 00:00:00 2001 From: SergeyEzhin Date: Thu, 23 Mar 2023 20:07:05 +0400 Subject: [PATCH 9/9] [DE mobile] Correct fields in protection settings --- .../src/view/settings/DocumentProtection.jsx | 44 ++++++++----------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/apps/documenteditor/mobile/src/view/settings/DocumentProtection.jsx b/apps/documenteditor/mobile/src/view/settings/DocumentProtection.jsx index 7769c0d62a..5f5d67d43b 100644 --- a/apps/documenteditor/mobile/src/view/settings/DocumentProtection.jsx +++ b/apps/documenteditor/mobile/src/view/settings/DocumentProtection.jsx @@ -54,34 +54,26 @@ const ProtectionDocumentView = inject("storeAppOptions")(observer(props => { }} /> - {isRequirePassword && <> - {Device.android ? - - changePassword(e.target.value)} /> - changeRepeationPassword(e.target.value)} /> - - : - - changePassword(e.target.value)} - className={isIos ? 'list-input-right' : ''} - /> - changeRepeationPassword(e.target.value)} - className={isIos ? 'list-input-right' : ''} - /> - - } + + changePassword(e.target.value)} + className={isIos ? 'list-input-right' : ''} + /> + changeRepeationPassword(e.target.value)} + className={isIos ? 'list-input-right' : ''} + /> +

If the password is forgotten or lost, it cannot be recovered.