diff --git a/apps/common/mobile/resources/css/skeleton.css b/apps/common/mobile/resources/css/skeleton.css index 85c8c2031..f5a0aa1a7 100644 --- a/apps/common/mobile/resources/css/skeleton.css +++ b/apps/common/mobile/resources/css/skeleton.css @@ -127,7 +127,9 @@ body.theme-type-dark { :root .theme-type-dark { --f7-navbar-bg-color: #232323; + --f7-bars-bg-color-rgb: 35,35,35; --f7-subnavbar-bg-color: #232323; + --f7-bars-translucent-opacity: 1; } .md .word-editor { diff --git a/apps/documenteditor/mobile/src/controller/Toolbar.jsx b/apps/documenteditor/mobile/src/controller/Toolbar.jsx index e896757d8..534d362f8 100644 --- a/apps/documenteditor/mobile/src/controller/Toolbar.jsx +++ b/apps/documenteditor/mobile/src/controller/Toolbar.jsx @@ -16,39 +16,24 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeReview', 'sto const stateDisplayMode = displayMode == "final" || displayMode == "original" ? true : false; const displayCollaboration = props.users.hasEditUsers || appOptions.canViewComments || appOptions.canReview || appOptions.canViewReview; const readerMode = appOptions.readerMode; - const objectLocked = props.storeFocusObjects.objectLocked; - const storeToolbarSettings = props.storeToolbarSettings; const isCanUndo = storeToolbarSettings.isCanUndo; const isCanRedo = storeToolbarSettings.isCanRedo; const disabledControls = storeToolbarSettings.disabledControls; const disabledEditControls = storeToolbarSettings.disabledEditControls; const disabledSettings = storeToolbarSettings.disabledSettings; - const showEditDocument = !appOptions.isEdit && appOptions.canEdit && appOptions.canRequestEditRights; - const docInfo = props.storeDocumentInfo; const docExt = docInfo.dataDoc ? docInfo.dataDoc.fileType : ''; const docTitle = docInfo.dataDoc ? docInfo.dataDoc.title : ''; - const sensitivity = 20; - let touchStartY = 0; - let touchEndY = 0; - useEffect(() => { - const sdk = document.querySelector('#editor_sdk'); - Common.Gateway.on('init', loadConfig); Common.Notifications.on('toolbar:activatecontrols', activateControls); Common.Notifications.on('toolbar:deactivateeditcontrols', deactivateEditControls); Common.Notifications.on('goback', goBack); - if(isViewer) { - sdk.addEventListener('touchstart', handleTouchStart); - sdk.addEventListener('touchend', handleTouchEnd); - } - if (isDisconnected) { f7.popover.close(); f7.sheet.close(); @@ -59,36 +44,58 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeReview', 'sto Common.Notifications.off('toolbar:activatecontrols', activateControls); Common.Notifications.off('toolbar:deactivateeditcontrols', deactivateEditControls); Common.Notifications.off('goback', goBack); + } + }, []); + useEffect(() => { + const api = Common.EditorApi.get(); + const navbarBgHeight = document.querySelector('.navbar-bg').clientHeight; + const subnavbarHeight = document.querySelector('.subnavbar').clientHeight; + const navbarHeight = navbarBgHeight + subnavbarHeight; + + const onEngineCreated = api => { if(isViewer) { - sdk.removeEventListener('touchstart', handleTouchStart); - sdk.removeEventListener('touchend', handleTouchEnd); + api.SetMobileTopOffset(navbarHeight, navbarHeight); + api.asc_registerCallback('onMobileScrollDelta', scrollHandler); } + }; + + if (!api) { + Common.Notifications.on('engineCreated', onEngineCreated); + } else { + onEngineCreated(api); } - }); - // Touch handlers + return () => { + const api = Common.EditorApi.get(); - const checkDirection = () => { - const diff = touchStartY - touchEndY; - - if(Math.abs(diff) > sensitivity) { - if(diff > 0) { - // f7.navbar.show('.main-navbar'); - } else { - // f7.navbar.hide('.main-navbar'); + if (api) { + api.SetMobileTopOffset(navbarHeight, navbarHeight); + api.asc_unregisterCallback('onMobileScrollDelta', scrollHandler); } + + Common.Notifications.off('engineCreated', onEngineCreated); } - }; + }, [isViewer]); - const handleTouchStart = e => { - touchStartY = e.changedTouches[0].screenY; - }; + // Scroll handler - const handleTouchEnd = e => { - touchEndY = e.changedTouches[0].screenY; - checkDirection(); - }; + const scrollHandler = offset => { + const api = Common.EditorApi.get(); + const navbarBgHeight = document.querySelector('.navbar-bg').clientHeight; + const subnavbarHeight = document.querySelector('.subnavbar').clientHeight; + const navbarHeight = navbarBgHeight + subnavbarHeight; + + if(offset > navbarHeight) { + f7.navbar.hide('.main-navbar'); + props.closeOptions('fab'); + api.SetMobileTopOffset(undefined, 0); + } else if(offset < -navbarHeight) { + f7.navbar.show('.main-navbar'); + props.openOptions('fab'); + api.SetMobileTopOffset(undefined, navbarHeight); + } + } // Back button const [isShowBack, setShowBack] = useState(appOptions.canBackToFolder); diff --git a/apps/documenteditor/mobile/src/less/app.less b/apps/documenteditor/mobile/src/less/app.less index 7487acd10..b5f1bc2ff 100644 --- a/apps/documenteditor/mobile/src/less/app.less +++ b/apps/documenteditor/mobile/src/less/app.less @@ -69,6 +69,17 @@ } } +.page.page-with-subnavbar { + .page-content, &.page-with-logo .page-content { + --f7-page-subnavbar-offset: 0; + padding-top: 0; + } +} + +.page.editor > .page-content { + --f7-page-navbar-offset: 0; +} + // Review .page-review { --f7-toolbar-link-color: @brandColor; @@ -338,28 +349,32 @@ } } -// Snackbar animation -.snackbar-enter { - opacity: 0; -} -.snackbar-enter-active { - opacity: 1; - transition: opacity 300ms; -} -.snackbar-exit { - opacity: 1; -} -.snackbar-exit-active { - opacity: 0; - transition: opacity 300ms; -} - // FAB -.fab a { - background-color: @background-primary; - &:focus, &:focus-within, &:active, &.active-state { +.fab { + z-index: 10000; + a { background-color: @background-primary; + + &:focus, &:focus-within, &:active, &.active-state { + background-color: @background-primary; + } } } +// Snackbar and FAB animation +.snackbar-enter, .fab-enter { + opacity: 0; +} +.snackbar-enter-active, .fab-enter-active { + opacity: 1; + transition: opacity 300ms; +} +.snackbar-exit, .fab-exit { + opacity: 1; +} +.snackbar-exit-active, .fab-exit-active { + opacity: 0; + transition: opacity 300ms; +} + diff --git a/apps/documenteditor/mobile/src/page/main.jsx b/apps/documenteditor/mobile/src/page/main.jsx index f0c88ee5e..b49ecc209 100644 --- a/apps/documenteditor/mobile/src/page/main.jsx +++ b/apps/documenteditor/mobile/src/page/main.jsx @@ -29,7 +29,8 @@ class MainPage extends Component { navigationVisible: false, addLinkSettingsVisible: false, editLinkSettingsVisible: false, - snackbarVisible: false + snackbarVisible: false, + fabVisible: true }; } @@ -41,80 +42,71 @@ class MainPage extends Component { handleClickToOpenOptions = (opts, showOpts) => { f7.popover.close('.document-menu.modal-in', false); + + let opened = false; + const newState = {}; - setTimeout(() => { - let opened = false; - const newState = {}; - if ( opts === 'edit' ) { - this.state.editOptionsVisible && (opened = true); - newState.editOptionsVisible = true; - } else if ( opts === 'add' ) { - this.state.addOptionsVisible && (opened = true); - newState.addOptionsVisible = true; - newState.addShowOptions = showOpts; - } else if ( opts === 'settings' ) { - this.state.settingsVisible && (opened = true); - newState.settingsVisible = true; - } else if ( opts === 'coauth' ) { - this.state.collaborationVisible && (opened = true); - newState.collaborationVisible = true; - } else if( opts === 'navigation') { - this.state.navigationVisible && (opened = true); - newState.navigationVisible = true; - } else if ( opts === 'add-link') { - this.state.addLinkSettingsVisible && (opened = true); - newState.addLinkSettingsVisible = true; - } else if( opts === 'edit-link') { - this.state.editLinkSettingsVisible && (opened = true); - newState.editLinkSettingsVisible = true; - } else if( opts === 'snackbar') { - this.state.snackbarVisible && (opened = true); - newState.snackbarVisible = true; - } + if (opts === 'edit') { + this.state.editOptionsVisible && (opened = true); + newState.editOptionsVisible = true; + } else if (opts === 'add') { + this.state.addOptionsVisible && (opened = true); + newState.addOptionsVisible = true; + newState.addShowOptions = showOpts; + } else if (opts === 'settings') { + this.state.settingsVisible && (opened = true); + newState.settingsVisible = true; + } else if (opts === 'coauth') { + this.state.collaborationVisible && (opened = true); + newState.collaborationVisible = true; + } else if (opts === 'navigation') { + this.state.navigationVisible && (opened = true); + newState.navigationVisible = true; + } else if (opts === 'add-link') { + this.state.addLinkSettingsVisible && (opened = true); + newState.addLinkSettingsVisible = true; + } else if (opts === 'edit-link') { + this.state.editLinkSettingsVisible && (opened = true); + newState.editLinkSettingsVisible = true; + } else if (opts === 'snackbar') { + newState.snackbarVisible = true; + } else if (opts === 'fab') { + newState.fabVisible = true; + } - for (let key in this.state) { - if (this.state[key] && !opened) { - setTimeout(() => { - this.handleClickToOpenOptions(opts, showOpts); - }, 10); - return; - } + if (!opened) { + this.setState(newState); + if ((opts === 'edit' || opts === 'coauth') && Device.phone) { + f7.navbar.hide('.main-navbar'); } - - if (!opened) { - this.setState(newState); - if ((opts === 'edit' || opts === 'coauth') && Device.phone) { - f7.navbar.hide('.main-navbar'); - } - } - }, 10); + } }; handleOptionsViewClosed = opts => { - setTimeout(() => { - this.setState(state => { - if ( opts == 'edit' ) - return {editOptionsVisible: false}; - else if ( opts == 'add' ) - return {addOptionsVisible: false, addShowOptions: null}; - else if ( opts == 'settings' ) - return {settingsVisible: false}; - else if ( opts == 'coauth' ) - return {collaborationVisible: false}; - else if( opts == 'navigation') - return {navigationVisible: false}; - else if ( opts === 'add-link') - return {addLinkSettingsVisible: false}; - else if( opts === 'edit-link') - return {editLinkSettingsVisible: false}; - else if( opts == 'snackbar') - return {snackbarVisible: false} - }); - if ((opts === 'edit' || opts === 'coauth') && Device.phone) { - f7.navbar.show('.main-navbar'); - } - }, 1); + this.setState(state => { + if (opts == 'edit') + return {editOptionsVisible: false}; + else if (opts == 'add') + return {addOptionsVisible: false, addShowOptions: null}; + else if (opts == 'settings') + return {settingsVisible: false}; + else if (opts == 'coauth') + return {collaborationVisible: false}; + else if (opts == 'navigation') + return {navigationVisible: false}; + else if (opts === 'add-link') + return {addLinkSettingsVisible: false}; + else if (opts === 'edit-link') + return {editLinkSettingsVisible: false}; + else if (opts == 'snackbar') + return {snackbarVisible: false} + else if (opts == 'fab') + return {fabVisible: false} + }); + if ((opts === 'edit' || opts === 'coauth') && Device.phone) { + f7.navbar.show('.main-navbar'); + } }; turnOffViewerMode() { @@ -124,6 +116,8 @@ class MainPage extends Component { appOptions.changeViewerMode(); api.asc_removeRestriction(Asc.c_oAscRestrictionType.View) api.asc_addRestriction(Asc.c_oAscRestrictionType.None); + + f7.navbar.show('.main-navbar'); }; render() { @@ -139,8 +133,9 @@ class MainPage extends Component { const isMobileView = appOptions.isMobileView; const disabledControls = storeToolbarSettings.disabledControls; const disabledSettings = storeToolbarSettings.disabledSettings; - const config = appOptions.config; const isProtected = appOptions.isProtected; + const isFabShow = isViewer && !disabledSettings && !disabledControls && !isDisconnected && isAvailableExt && isEdit && !isProtected; + const config = appOptions.config; let showLogo = !(config.customization && (config.customization.loaderName || config.customization.loaderLogo)); if (!Object.keys(config).length) { @@ -150,9 +145,6 @@ class MainPage extends Component { const showPlaceholder = !appOptions.isDocReady && (!config.customization || !(config.customization.loaderName || config.customization.loaderLogo)); const isBranding = appOptions.canBranding || appOptions.canBrandingExt; - if ($$('.skl-container').length) { - $$('.skl-container').remove(); - } return ( @@ -203,8 +195,25 @@ class MainPage extends Component { } {/* { - Device.phone ? null : - } */} + Device.phone ? null : + } */} + { + if(!isAppearing) { + this.setState({ + snackbarVisible: false + }); + } + }} + > + + { !this.state.editOptionsVisible ? null : @@ -235,24 +244,19 @@ class MainPage extends Component { !this.state.navigationVisible ? null : } - { + {isFabShow && - + this.turnOffViewerMode()}> + + } - {isViewer && !disabledSettings && !disabledControls && !isDisconnected && isAvailableExt && isEdit && !isProtected && - this.turnOffViewerMode()}> - - - - } {appOptions.isDocReady && } ) diff --git a/apps/documenteditor/mobile/src/view/Toolbar.jsx b/apps/documenteditor/mobile/src/view/Toolbar.jsx index d642d8bd9..619ee7f69 100644 --- a/apps/documenteditor/mobile/src/view/Toolbar.jsx +++ b/apps/documenteditor/mobile/src/view/Toolbar.jsx @@ -62,12 +62,9 @@ const ToolbarView = props => { onRedoClick: props.onRedo })} {/*isAvailableExt && !props.disabledControls &&*/} - {((isViewer || !Device.phone) && isAvailableExt) && { - await props.changeMobileView(); - await props.openOptions('snackbar'); - setTimeout(() => { - props.closeOptions('snackbar'); - }, 1500); + {(isViewer || !Device.phone) && { + props.changeMobileView(); + props.openOptions('snackbar'); }}>} {(props.showEditDocument && !isViewer) && @@ -79,8 +76,8 @@ const ToolbarView = props => { })} {/*props.displayCollaboration &&*/} {Device.phone ? null : } - {window.matchMedia("(min-width: 360px)").matches ? props.openOptions('coauth')}> : null} - props.openOptions('settings')}> + {window.matchMedia("(min-width: 360px)").matches ? props.openOptions('coauth')}> : null} + props.openOptions('settings')}> ) diff --git a/apps/documenteditor/mobile/src/view/settings/Settings.jsx b/apps/documenteditor/mobile/src/view/settings/Settings.jsx index 2533eace1..9ffb8d90a 100644 --- a/apps/documenteditor/mobile/src/view/settings/Settings.jsx +++ b/apps/documenteditor/mobile/src/view/settings/Settings.jsx @@ -171,13 +171,10 @@ const SettingsList = inject("storeAppOptions", "storeReview")(observer(props => {!isViewer && Device.phone && - { - await props.onChangeMobileView(); - await closeModal(); - await props.openOptions('snackbar'); - setTimeout(() => { - props.closeOptions('snackbar'); - }, 1500); + { + closeModal(); + props.onChangeMobileView(); + props.openOptions('snackbar'); }} /> }