Merge pull request #2094 from ONLYOFFICE/feature/Bug_58655

Feature/bug 58655
This commit is contained in:
maxkadushkin 2022-12-20 19:17:00 +03:00 committed by GitHub
commit ed0bad17d5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 176 additions and 154 deletions

View file

@ -127,7 +127,9 @@ body.theme-type-dark {
:root .theme-type-dark { :root .theme-type-dark {
--f7-navbar-bg-color: #232323; --f7-navbar-bg-color: #232323;
--f7-bars-bg-color-rgb: 35,35,35;
--f7-subnavbar-bg-color: #232323; --f7-subnavbar-bg-color: #232323;
--f7-bars-translucent-opacity: 1;
} }
.md .word-editor { .md .word-editor {

View file

@ -16,39 +16,24 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeReview', 'sto
const stateDisplayMode = displayMode == "final" || displayMode == "original" ? true : false; const stateDisplayMode = displayMode == "final" || displayMode == "original" ? true : false;
const displayCollaboration = props.users.hasEditUsers || appOptions.canViewComments || appOptions.canReview || appOptions.canViewReview; const displayCollaboration = props.users.hasEditUsers || appOptions.canViewComments || appOptions.canReview || appOptions.canViewReview;
const readerMode = appOptions.readerMode; const readerMode = appOptions.readerMode;
const objectLocked = props.storeFocusObjects.objectLocked; const objectLocked = props.storeFocusObjects.objectLocked;
const storeToolbarSettings = props.storeToolbarSettings; const storeToolbarSettings = props.storeToolbarSettings;
const isCanUndo = storeToolbarSettings.isCanUndo; const isCanUndo = storeToolbarSettings.isCanUndo;
const isCanRedo = storeToolbarSettings.isCanRedo; const isCanRedo = storeToolbarSettings.isCanRedo;
const disabledControls = storeToolbarSettings.disabledControls; const disabledControls = storeToolbarSettings.disabledControls;
const disabledEditControls = storeToolbarSettings.disabledEditControls; const disabledEditControls = storeToolbarSettings.disabledEditControls;
const disabledSettings = storeToolbarSettings.disabledSettings; const disabledSettings = storeToolbarSettings.disabledSettings;
const showEditDocument = !appOptions.isEdit && appOptions.canEdit && appOptions.canRequestEditRights; const showEditDocument = !appOptions.isEdit && appOptions.canEdit && appOptions.canRequestEditRights;
const docInfo = props.storeDocumentInfo; const docInfo = props.storeDocumentInfo;
const docExt = docInfo.dataDoc ? docInfo.dataDoc.fileType : ''; const docExt = docInfo.dataDoc ? docInfo.dataDoc.fileType : '';
const docTitle = docInfo.dataDoc ? docInfo.dataDoc.title : ''; const docTitle = docInfo.dataDoc ? docInfo.dataDoc.title : '';
const sensitivity = 20;
let touchStartY = 0;
let touchEndY = 0;
useEffect(() => { useEffect(() => {
const sdk = document.querySelector('#editor_sdk');
Common.Gateway.on('init', loadConfig); Common.Gateway.on('init', loadConfig);
Common.Notifications.on('toolbar:activatecontrols', activateControls); Common.Notifications.on('toolbar:activatecontrols', activateControls);
Common.Notifications.on('toolbar:deactivateeditcontrols', deactivateEditControls); Common.Notifications.on('toolbar:deactivateeditcontrols', deactivateEditControls);
Common.Notifications.on('goback', goBack); Common.Notifications.on('goback', goBack);
if(isViewer) {
sdk.addEventListener('touchstart', handleTouchStart);
sdk.addEventListener('touchend', handleTouchEnd);
}
if (isDisconnected) { if (isDisconnected) {
f7.popover.close(); f7.popover.close();
f7.sheet.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:activatecontrols', activateControls);
Common.Notifications.off('toolbar:deactivateeditcontrols', deactivateEditControls); Common.Notifications.off('toolbar:deactivateeditcontrols', deactivateEditControls);
Common.Notifications.off('goback', goBack); 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) { if(isViewer) {
sdk.removeEventListener('touchstart', handleTouchStart); api.SetMobileTopOffset(navbarHeight, navbarHeight);
sdk.removeEventListener('touchend', handleTouchEnd); api.asc_registerCallback('onMobileScrollDelta', scrollHandler);
} }
} };
});
// Touch handlers if (!api) {
Common.Notifications.on('engineCreated', onEngineCreated);
const checkDirection = () => {
const diff = touchStartY - touchEndY;
if(Math.abs(diff) > sensitivity) {
if(diff > 0) {
// f7.navbar.show('.main-navbar');
} else { } else {
// f7.navbar.hide('.main-navbar'); onEngineCreated(api);
}
return () => {
const api = Common.EditorApi.get();
if (api) {
api.SetMobileTopOffset(navbarHeight, navbarHeight);
api.asc_unregisterCallback('onMobileScrollDelta', scrollHandler);
}
Common.Notifications.off('engineCreated', onEngineCreated);
}
}, [isViewer]);
// Scroll handler
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);
} }
} }
};
const handleTouchStart = e => {
touchStartY = e.changedTouches[0].screenY;
};
const handleTouchEnd = e => {
touchEndY = e.changedTouches[0].screenY;
checkDirection();
};
// Back button // Back button
const [isShowBack, setShowBack] = useState(appOptions.canBackToFolder); const [isShowBack, setShowBack] = useState(appOptions.canBackToFolder);

View file

@ -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 // Review
.page-review { .page-review {
--f7-toolbar-link-color: @brandColor; --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
.fab a { .fab {
z-index: 10000;
a {
background-color: @background-primary; background-color: @background-primary;
&:focus, &:focus-within, &:active, &.active-state { &:focus, &:focus-within, &:active, &.active-state {
background-color: @background-primary; 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;
}

View file

@ -29,7 +29,8 @@ class MainPage extends Component {
navigationVisible: false, navigationVisible: false,
addLinkSettingsVisible: false, addLinkSettingsVisible: false,
editLinkSettingsVisible: false, editLinkSettingsVisible: false,
snackbarVisible: false snackbarVisible: false,
fabVisible: true
}; };
} }
@ -42,9 +43,9 @@ class MainPage extends Component {
handleClickToOpenOptions = (opts, showOpts) => { handleClickToOpenOptions = (opts, showOpts) => {
f7.popover.close('.document-menu.modal-in', false); f7.popover.close('.document-menu.modal-in', false);
setTimeout(() => {
let opened = false; let opened = false;
const newState = {}; const newState = {};
if (opts === 'edit') { if (opts === 'edit') {
this.state.editOptionsVisible && (opened = true); this.state.editOptionsVisible && (opened = true);
newState.editOptionsVisible = true; newState.editOptionsVisible = true;
@ -68,17 +69,9 @@ class MainPage extends Component {
this.state.editLinkSettingsVisible && (opened = true); this.state.editLinkSettingsVisible && (opened = true);
newState.editLinkSettingsVisible = true; newState.editLinkSettingsVisible = true;
} else if (opts === 'snackbar') { } else if (opts === 'snackbar') {
this.state.snackbarVisible && (opened = true);
newState.snackbarVisible = true; 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) { if (!opened) {
@ -87,11 +80,9 @@ class MainPage extends Component {
f7.navbar.hide('.main-navbar'); f7.navbar.hide('.main-navbar');
} }
} }
}, 10);
}; };
handleOptionsViewClosed = opts => { handleOptionsViewClosed = opts => {
setTimeout(() => {
this.setState(state => { this.setState(state => {
if (opts == 'edit') if (opts == 'edit')
return {editOptionsVisible: false}; return {editOptionsVisible: false};
@ -109,12 +100,13 @@ class MainPage extends Component {
return {editLinkSettingsVisible: false}; return {editLinkSettingsVisible: false};
else if (opts == 'snackbar') else if (opts == 'snackbar')
return {snackbarVisible: false} return {snackbarVisible: false}
else if (opts == 'fab')
return {fabVisible: false}
}); });
if ((opts === 'edit' || opts === 'coauth') && Device.phone) { if ((opts === 'edit' || opts === 'coauth') && Device.phone) {
f7.navbar.show('.main-navbar'); f7.navbar.show('.main-navbar');
} }
}, 1);
}; };
turnOffViewerMode() { turnOffViewerMode() {
@ -124,6 +116,8 @@ class MainPage extends Component {
appOptions.changeViewerMode(); appOptions.changeViewerMode();
api.asc_removeRestriction(Asc.c_oAscRestrictionType.View) api.asc_removeRestriction(Asc.c_oAscRestrictionType.View)
api.asc_addRestriction(Asc.c_oAscRestrictionType.None); api.asc_addRestriction(Asc.c_oAscRestrictionType.None);
f7.navbar.show('.main-navbar');
}; };
render() { render() {
@ -139,8 +133,9 @@ class MainPage extends Component {
const isMobileView = appOptions.isMobileView; const isMobileView = appOptions.isMobileView;
const disabledControls = storeToolbarSettings.disabledControls; const disabledControls = storeToolbarSettings.disabledControls;
const disabledSettings = storeToolbarSettings.disabledSettings; const disabledSettings = storeToolbarSettings.disabledSettings;
const config = appOptions.config;
const isProtected = appOptions.isProtected; 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)); let showLogo = !(config.customization && (config.customization.loaderName || config.customization.loaderLogo));
if (!Object.keys(config).length) { 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 showPlaceholder = !appOptions.isDocReady && (!config.customization || !(config.customization.loaderName || config.customization.loaderLogo));
const isBranding = appOptions.canBranding || appOptions.canBrandingExt; const isBranding = appOptions.canBranding || appOptions.canBrandingExt;
if ($$('.skl-container').length) {
$$('.skl-container').remove();
}
return ( return (
<Page name="home" className={`editor${showLogo ? ' page-with-logo' : ''}`}> <Page name="home" className={`editor${showLogo ? ' page-with-logo' : ''}`}>
@ -205,6 +197,23 @@ class MainPage extends Component {
{/* { {/* {
Device.phone ? null : <SearchSettings /> Device.phone ? null : <SearchSettings />
} */} } */}
<CSSTransition
in={this.state.snackbarVisible}
timeout={1500}
classNames="snackbar"
mountOnEnter
unmountOnExit
onEntered={(node, isAppearing) => {
if(!isAppearing) {
this.setState({
snackbarVisible: false
});
}
}}
>
<Snackbar
text={isMobileView ? t("Toolbar.textSwitchedMobileView") : t("Toolbar.textSwitchedStandardView")}/>
</CSSTransition>
<SearchSettings useSuspense={false}/> <SearchSettings useSuspense={false}/>
{ {
!this.state.editOptionsVisible ? null : !this.state.editOptionsVisible ? null :
@ -235,23 +244,18 @@ class MainPage extends Component {
!this.state.navigationVisible ? null : !this.state.navigationVisible ? null :
<NavigationController onclosed={this.handleOptionsViewClosed.bind(this, 'navigation')}/> <NavigationController onclosed={this.handleOptionsViewClosed.bind(this, 'navigation')}/>
} }
{ {isFabShow &&
<CSSTransition <CSSTransition
in={this.state.snackbarVisible} in={this.state.fabVisible}
timeout={500} timeout={500}
classNames="snackbar" classNames="fab"
mountOnEnter mountOnEnter
unmountOnExit unmountOnExit
> >
<Snackbar
text={isMobileView ? t("Toolbar.textSwitchedMobileView") : t("Toolbar.textSwitchedStandardView")}/>
</CSSTransition>
}
{isViewer && !disabledSettings && !disabledControls && !isDisconnected && isAvailableExt && isEdit && !isProtected &&
<Fab position="right-bottom" slot="fixed" onClick={() => this.turnOffViewerMode()}> <Fab position="right-bottom" slot="fixed" onClick={() => this.turnOffViewerMode()}>
<Icon icon="icon-edit-mode"/> <Icon icon="icon-edit-mode"/>
</Fab> </Fab>
</CSSTransition>
} }
{appOptions.isDocReady && <ContextMenu openOptions={this.handleClickToOpenOptions.bind(this)}/>} {appOptions.isDocReady && <ContextMenu openOptions={this.handleClickToOpenOptions.bind(this)}/>}
</Page> </Page>

View file

@ -62,12 +62,9 @@ const ToolbarView = props => {
onRedoClick: props.onRedo onRedoClick: props.onRedo
})} })}
{/*isAvailableExt && !props.disabledControls &&*/} {/*isAvailableExt && !props.disabledControls &&*/}
{((isViewer || !Device.phone) && isAvailableExt) && <Link className={(!isAvailableExt || props.disabledControls) && 'disabled'} icon={isMobileView ? 'icon-standard-view' : 'icon-mobile-view'} href={false} onClick={async e => { {(isViewer || !Device.phone) && <Link className={(!isAvailableExt || props.disabledControls) && 'disabled'} icon={isMobileView ? 'icon-standard-view' : 'icon-mobile-view'} href={false} onClick={() => {
await props.changeMobileView(); props.changeMobileView();
await props.openOptions('snackbar'); props.openOptions('snackbar');
setTimeout(() => {
props.closeOptions('snackbar');
}, 1500);
}}></Link>} }}></Link>}
{(props.showEditDocument && !isViewer) && {(props.showEditDocument && !isViewer) &&
<Link className={props.disabledControls ? 'disabled' : ''} icon='icon-edit' href={false} onClick={props.onEditDocument}></Link> <Link className={props.disabledControls ? 'disabled' : ''} icon='icon-edit' href={false} onClick={props.onEditDocument}></Link>
@ -79,8 +76,8 @@ const ToolbarView = props => {
})} })}
{/*props.displayCollaboration &&*/} {/*props.displayCollaboration &&*/}
{Device.phone ? null : <Link className={(props.disabledControls || props.readerMode) && 'disabled'} icon='icon-search' searchbarEnable='.searchbar' href={false}></Link>} {Device.phone ? null : <Link className={(props.disabledControls || props.readerMode) && 'disabled'} icon='icon-search' searchbarEnable='.searchbar' href={false}></Link>}
{window.matchMedia("(min-width: 360px)").matches ? <Link className={props.disabledControls && 'disabled'} id='btn-coauth' href={false} icon='icon-collaboration' onClick={e => props.openOptions('coauth')}></Link> : null} {window.matchMedia("(min-width: 360px)").matches ? <Link className={props.disabledControls && 'disabled'} id='btn-coauth' href={false} icon='icon-collaboration' onClick={() => props.openOptions('coauth')}></Link> : null}
<Link className={(props.disabledSettings || props.disabledControls || isDisconnected) && 'disabled'} id='btn-settings' icon='icon-settings' href={false} onClick={e => props.openOptions('settings')}></Link> <Link className={(props.disabledSettings || props.disabledControls || isDisconnected) && 'disabled'} id='btn-settings' icon='icon-settings' href={false} onClick={() => props.openOptions('settings')}></Link>
</NavRight> </NavRight>
</Fragment> </Fragment>
) )

View file

@ -171,13 +171,10 @@ const SettingsList = inject("storeAppOptions", "storeReview")(observer(props =>
{!isViewer && Device.phone && {!isViewer && Device.phone &&
<ListItem title={t('Settings.textMobileView')}> <ListItem title={t('Settings.textMobileView')}>
<Icon slot="media" icon="icon-mobile-view"></Icon> <Icon slot="media" icon="icon-mobile-view"></Icon>
<Toggle checked={isMobileView} onToggleChange={async () => { <Toggle checked={isMobileView} onToggleChange={() => {
await props.onChangeMobileView(); closeModal();
await closeModal(); props.onChangeMobileView();
await props.openOptions('snackbar'); props.openOptions('snackbar');
setTimeout(() => {
props.closeOptions('snackbar');
}, 1500);
}} /> }} />
</ListItem> </ListItem>
} }