React on window resize; expand menu automatically

pull/6763/head
Inga Mai 6 years ago
parent c2d0d25feb
commit 52140e51ad
  1. 2
      frontend/src/app/components/resizer/main-menu-resizer.component.ts
  2. 2
      frontend/src/app/components/resizer/main-menu-toggle.component.ts
  3. 59
      frontend/src/app/components/resizer/main-menu-toggle.service.ts

@ -150,7 +150,7 @@ export class MainMenuResizerComponent implements OnInit, OnDestroy {
this.oldPosition = e.clientX; this.oldPosition = e.clientX;
this.elementWidth = this.elementWidth + delta; this.elementWidth = this.elementWidth + delta;
this.toggleService.setWidth(this.elementWidth); this.toggleService.saveWidth(this.elementWidth);
} }
} }

@ -38,7 +38,7 @@ import {Injector} from "@angular/core";
@Component({ @Component({
selector: 'main-menu-toggle', selector: 'main-menu-toggle',
template: ` template: `
<div *ngIf="this.currentProject.id !== null || toggleService.isMobile()" id="main-menu-toggle" <div *ngIf="this.currentProject.id !== null || toggleService.isMobile" id="main-menu-toggle"
aria-haspopup="true" aria-haspopup="true"
[attr.title]="toggleTitle" [attr.title]="toggleTitle"
(accessibleClick)="toggleService.toggleNavigation($event)" (accessibleClick)="toggleService.toggleNavigation($event)"

@ -31,6 +31,9 @@ import {BehaviorSubject} from 'rxjs';
import {I18nService} from "core-app/modules/common/i18n/i18n.service"; import {I18nService} from "core-app/modules/common/i18n/i18n.service";
import {CurrentProjectService} from "core-components/projects/current-project.service"; import {CurrentProjectService} from "core-components/projects/current-project.service";
import {Injector} from "@angular/core"; import {Injector} from "@angular/core";
import {fromEvent} from "rxjs/observable/fromEvent";
import {Observable} from "rxjs/Observable";
import {Subscription} from "rxjs/Subscription";
@Injectable() @Injectable()
export class MainMenuToggleService { export class MainMenuToggleService {
@ -39,6 +42,7 @@ export class MainMenuToggleService {
private elementWidth:number; private elementWidth:number;
private readonly localStorageKey:string = 'openProject-mainMenuWidth'; private readonly localStorageKey:string = 'openProject-mainMenuWidth';
private readonly defaultWidth:number = 230; private readonly defaultWidth:number = 230;
private readonly currentProject:CurrentProjectService = this.injector.get(CurrentProjectService);
private global = (window as any); private global = (window as any);
private htmlNode = document.getElementsByTagName('html')[0]; private htmlNode = document.getElementsByTagName('html')[0];
@ -53,6 +57,9 @@ export class MainMenuToggleService {
private changeData = new BehaviorSubject<any>({}); private changeData = new BehaviorSubject<any>({});
public changeData$ = this.changeData.asObservable(); public changeData$ = this.changeData.asObservable();
private resizeObservable$:Observable<Event>;
private resizeSubscription$:Subscription;
constructor(protected I18n:I18nService, constructor(protected I18n:I18nService,
protected injector:Injector) { protected injector:Injector) {
} }
@ -74,9 +81,12 @@ export class MainMenuToggleService {
} }
// mobile version default: hide menu on initialization // mobile version default: hide menu on initialization
if (this.isMobile()) { if (this.isMobile) {
this.closeMenu(); this.closeMenu();
} }
// Listen on changes of the screen size
this.onWindowResize();
} }
// click on arrow or hamburger icon // click on arrow or hamburger icon
@ -86,8 +96,8 @@ export class MainMenuToggleService {
event.preventDefault(); event.preventDefault();
} }
if (!this.showNavigation()) { // sidebar is hidden -> show menu if (!this.showNavigation) { // sidebar is hidden -> show menu
if (this.isMobile()) { // mobile version if (this.isMobile) { // mobile version
this.setWidth(window.innerWidth); this.setWidth(window.innerWidth);
// On mobile the main menu shall close whenever you click outside the menu. // On mobile the main menu shall close whenever you click outside the menu.
this.setupAutocloseMainMenu(); this.setupAutocloseMainMenu();
@ -109,18 +119,22 @@ export class MainMenuToggleService {
} }
public closeMenu():void { public closeMenu():void {
this.saveWidth(0); if (this.isMobile) {
this.saveWidth(0); // save 0 in localStorage to open menu automatically on onWindowResize
} else {
this.setWidth(0);
}
this.hideElements.addClass('hidden-navigation'); this.hideElements.addClass('hidden-navigation');
} }
public closeWhenOnMobile():void { public closeWhenOnMobile():void {
if (this.isMobile()) { if (this.isMobile) {
this.closeMenu() this.closeMenu()
}; };
} }
private setToggleTitle():void { private setToggleTitle():void {
if (this.showNavigation()) { if (this.showNavigation) {
this.toggleTitle = this.I18n.t('js.label_hide_project_menu'); this.toggleTitle = this.I18n.t('js.label_hide_project_menu');
} else { } else {
this.toggleTitle = this.I18n.t('js.label_expand_project_menu'); this.toggleTitle = this.I18n.t('js.label_expand_project_menu');
@ -129,7 +143,7 @@ export class MainMenuToggleService {
} }
private addRemoveClassHidden():void { private addRemoveClassHidden():void {
this.hideElements.toggleClass('hidden-navigation', !this.showNavigation()); this.hideElements.toggleClass('hidden-navigation', !this.showNavigation);
} }
public saveWidth(width?:number):void { public saveWidth(width?:number):void {
@ -151,7 +165,7 @@ export class MainMenuToggleService {
this.snapBack(); this.snapBack();
this.ensureContentVisibility(); this.ensureContentVisibility();
this.global.showNavigation = this.showNavigation(); this.global.showNavigation = this.showNavigation;
this.addRemoveClassHidden(); this.addRemoveClassHidden();
this.htmlNode.style.setProperty("--main-menu-width", this.elementWidth + 'px'); this.htmlNode.style.setProperty("--main-menu-width", this.elementWidth + 'px');
} }
@ -162,7 +176,7 @@ export class MainMenuToggleService {
jQuery('#main-menu').on('focusout.main_menu', function (event) { jQuery('#main-menu').on('focusout.main_menu', function (event) {
// Check that main menu is not closed and that the `focusout` event is not a click on an element // Check that main menu is not closed and that the `focusout` event is not a click on an element
// that tries to close the menu anyways. // that tries to close the menu anyways.
if (!that.showNavigation() || document.getElementById('main-menu-toggle') === event.relatedTarget) { if (!that.showNavigation || document.getElementById('main-menu-toggle') === event.relatedTarget) {
return; return;
} }
else { else {
@ -191,11 +205,34 @@ export class MainMenuToggleService {
} }
} }
public isMobile():boolean { public get isMobile():boolean {
return (window.innerWidth < 680); return (window.innerWidth < 680);
} }
public showNavigation():boolean { public get showNavigation():boolean {
return (this.elementWidth > 10); return (this.elementWidth > 10);
} }
private get isGlobalPage():boolean {
return this.currentProject.id? false : true;
}
// Listen on changes of the window size on all global pages
// Expand menu automatically on desktop
private onWindowResize() {
if (!this.isGlobalPage) { // Listen only on global pages
return;
}
this.resizeObservable$ = fromEvent(window, 'resize')
this.resizeSubscription$ = this.resizeObservable$.subscribe( evt => {
if (!this.isMobile) {
let localStorage = parseInt(window.OpenProject.guardedLocalStorage(this.localStorageKey) as string);
if (localStorage > 0 && this.elementWidth > 10) { // Mobile menu is open and should stay open on desktop
this.setWidth(localStorage);
} else if (localStorage === 0 && this.elementWidth === 0) { // Mobile menu is closed and should expand on desktop
this.saveWidth(this.defaultWidth);
}
}
});
}
} }

Loading…
Cancel
Save