From d64eae031ae705a0b30aaf35f98c03de9bdb7e18 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Tue, 30 Mar 2021 23:11:49 +0300 Subject: [PATCH] [DE mobile] Make toolbar controller --- apps/common/mobile/lib/store/users.js | 15 +- .../mobile/resources/less/common-ios.less | 3 + apps/documenteditor/mobile/locale/en.json | 6 + .../mobile/src/controller/Main.jsx | 14 +- .../mobile/src/controller/Toolbar.jsx | 184 ++++++++++++++++++ apps/documenteditor/mobile/src/page/main.jsx | 20 +- .../mobile/src/view/Toolbar.jsx | 30 +++ 7 files changed, 246 insertions(+), 26 deletions(-) create mode 100644 apps/documenteditor/mobile/src/controller/Toolbar.jsx create mode 100644 apps/documenteditor/mobile/src/view/Toolbar.jsx diff --git a/apps/common/mobile/lib/store/users.js b/apps/common/mobile/lib/store/users.js index bf334c8e26..ab8e3ebdbb 100644 --- a/apps/common/mobile/lib/store/users.js +++ b/apps/common/mobile/lib/store/users.js @@ -1,5 +1,5 @@ -import {makeObservable, observable, action} from 'mobx'; +import {makeObservable, observable, action, computed} from 'mobx'; export class storeUsers { constructor() { @@ -10,7 +10,8 @@ export class storeUsers { setCurrentUser: action, connection: action, isDisconnected: observable, - resetDisconnected: action + resetDisconnected: action, + hasEditUsers: computed }) } @@ -80,4 +81,14 @@ export class storeUsers { }); return user; } + + get hasEditUsers () { + let length = 0; + this.users.forEach((item) => { + if ((item.asc_getState()!==false) && !item.asc_getView()) { + length++; + } + }); + return (length >= 1); + } } diff --git a/apps/common/mobile/resources/less/common-ios.less b/apps/common/mobile/resources/less/common-ios.less index 83ffd0b6fb..9a487cd603 100644 --- a/apps/common/mobile/resources/less/common-ios.less +++ b/apps/common/mobile/resources/less/common-ios.less @@ -31,6 +31,9 @@ } .navbar { + a.btn-doc-back { + width: 22px; + } background-color: var(--f7-navbar-bg-color); .title { font-weight: 600; diff --git a/apps/documenteditor/mobile/locale/en.json b/apps/documenteditor/mobile/locale/en.json index d85eb309cd..b83da7284e 100644 --- a/apps/documenteditor/mobile/locale/en.json +++ b/apps/documenteditor/mobile/locale/en.json @@ -27,6 +27,12 @@ "footnote text": "Footnote Text" } }, + "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" + }, "Common": { "ThemeColorPalette": { "textThemeColors": "Theme Colors", diff --git a/apps/documenteditor/mobile/src/controller/Main.jsx b/apps/documenteditor/mobile/src/controller/Main.jsx index 53d23e567a..4c969ac348 100644 --- a/apps/documenteditor/mobile/src/controller/Main.jsx +++ b/apps/documenteditor/mobile/src/controller/Main.jsx @@ -124,13 +124,13 @@ 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); + 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."); + } + } }; const onEditorPermissions = params => { diff --git a/apps/documenteditor/mobile/src/controller/Toolbar.jsx b/apps/documenteditor/mobile/src/controller/Toolbar.jsx new file mode 100644 index 0000000000..c1185e39fc --- /dev/null +++ b/apps/documenteditor/mobile/src/controller/Toolbar.jsx @@ -0,0 +1,184 @@ +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', 'storeReview')(props => { + const {t} = useTranslation(); + const _t = t("Toolbar", { returnObjects: true }); + + const appOptions = props.storeAppOptions; + const isDisconnected = props.users.isDisconnected; + const displayMode = props.storeReview.displayMode; + const stateDisplayMode = displayMode == "final" || displayMode == "original" ? true : false; + const displayCollaboration = props.users.hasEditUsers || appOptions.canViewComments || appOptions.canReview || appOptions.canViewReview; + + 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); + Common.Notifications.on('api:disconnect', onCoAuthoringDisconnect); + }; + 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); + + 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); + } + }); + + 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 (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 [isObjectLocked, setObjectLocked] = useState(false); + const onApiFocusObject = (objects) => { + if (isDisconnected) return; + + if (objects.length > 0) { + const getTopObject = (objects) => { + const arrObj = objects.reverse(); + let obj; + for (let i=0; i { + setDisabledEditControls(true); + if (enableDownload) { + //DE.getController('Settings').setMode({isDisconnected: true, enableDownload: enableDownload}); + } else { + setDisabledSettings(true); + } + }; + + const onCoAuthoringDisconnect = (enableDownload) => { + deactivateEditControls(enableDownload); + setCanUndo(false); + setCanRedo(false); + //props.closeOptions('add'); + //props.closeOptions('edit'); + //props.closeOptions('settings'); + }; + + return ( + + ) +}); + +export {ToolbarController as Toolbar}; \ 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 c3acac141d..e23bec1b5e 100644 --- a/apps/documenteditor/mobile/src/page/main.jsx +++ b/apps/documenteditor/mobile/src/page/main.jsx @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import { f7 } from 'framework7-react'; -import { Page, View, Navbar, NavLeft, NavRight, Link, Icon } from 'framework7-react'; +import { Page, View } from 'framework7-react'; import { inject } from "mobx-react"; import EditOptions from '../view/edit/Edit'; @@ -11,6 +11,7 @@ import Collaboration from '../../../../common/mobile/lib/view/collaboration/Coll 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 { constructor(props) { @@ -64,22 +65,7 @@ export default class MainPage extends Component { return ( {/* Top Navbar */} - -
- - - - - - this.handleClickToOpenOptions('edit')}> - this.handleClickToOpenOptions('add')}> - { Device.phone ? null : } - this.handleClickToOpenOptions('coauth')}> - this.handleClickToOpenOptions('settings')}> - - {/* { Device.phone ? null : } */} - -
+ {/* Page content */} diff --git a/apps/documenteditor/mobile/src/view/Toolbar.jsx b/apps/documenteditor/mobile/src/view/Toolbar.jsx new file mode 100644 index 0000000000..21eeac4fe2 --- /dev/null +++ b/apps/documenteditor/mobile/src/view/Toolbar.jsx @@ -0,0 +1,30 @@ +import React from 'react'; +import {Navbar, NavLeft, NavRight, NavTitle, Link, Icon} from 'framework7-react'; +import { Device } from '../../../../common/mobile/utils/device'; +import {Search} from "../controller/Search"; + +const ToolbarView = props => { + const disableEditBtn = props.isObjectLocked || props.stateDisplayMode || props.disabledEditControls; + return ( + +
+ + {props.isShowBack && } + + + + {!Device.phone && {props.docTitle}} + + props.openOptions('edit')}> + props.openOptions('add')}> + { Device.phone ? null : } + {props.displayCollaboration && props.openOptions('coauth')}>} + props.openOptions('settings')}> + + {/* { Device.phone ? null : } */} + +
+ ) +}; + +export default ToolbarView; \ No newline at end of file