Servicify menu, close menu on admin for small and medium screens

pull/2538/head
Rigel Kent 2020-03-07 13:50:26 +01:00 committed by Chocobozzz
parent 7b81edc854
commit 3b20bdd6dc
10 changed files with 102 additions and 30 deletions

View File

@ -4,10 +4,13 @@ import { RouteReuseStrategy, RouterModule, Routes } from '@angular/router'
import { PreloadSelectedModulesList } from './core'
import { AppComponent } from '@app/app.component'
import { CustomReuseStrategy } from '@app/core/routing/custom-reuse-strategy'
import { MenuGuards } from '@app/core/routing/menu-guard.service'
const routes: Routes = [
{
path: 'admin',
canActivate: [ MenuGuards.close() ],
canDeactivate: [ MenuGuards.open() ],
loadChildren: () => import('./+admin/admin.module').then(m => m.AdminModule)
},
{
@ -54,6 +57,7 @@ const routes: Routes = [
})
],
providers: [
MenuGuards.guards,
PreloadSelectedModulesList,
{ provide: RouteReuseStrategy, useClass: CustomReuseStrategy }
],

View File

@ -5,8 +5,8 @@
<div [ngClass]="{ 'user-logged-in': isUserLoggedIn(), 'user-not-logged-in': !isUserLoggedIn() }">
<div class="header">
<div class="top-left-block" [ngClass]="{ 'border-bottom': isMenuDisplayed === false }">
<span class="icon icon-menu" (click)="toggleMenu()"></span>
<div class="top-left-block" [ngClass]="{ 'border-bottom': menu.isMenuDisplayed === false }">
<span class="icon icon-menu" (click)="menu.toggleMenu()"></span>
<a class="peertube-title" [routerLink]="defaultRoute" title="Homepage" i18n-title>
<span class="icon icon-logo"></span>
@ -14,15 +14,15 @@
</a>
</div>
<div class="header-right" [ngClass]="{ 'border-bottom': isMenuDisplayed === false }">
<div class="header-right" [ngClass]="{ 'border-bottom': menu.isMenuDisplayed === false }">
<my-header class="w-100 d-flex justify-content-end"></my-header>
</div>
</div>
<div class="sub-header-container">
<my-menu *ngIf="isMenuDisplayed"></my-menu>
<my-menu *ngIf="menu.isMenuDisplayed"></my-menu>
<div id="content" tabindex="-1" class="main-col container-fluid" [ngClass]="{ expanded: isMenuDisplayed === false }">
<div id="content" tabindex="-1" class="main-col container-fluid" [ngClass]="{ expanded: menu.isMenuDisplayed === false }">
<div class="main-row">
<router-outlet></router-outlet>

View File

@ -18,6 +18,7 @@ import { InstanceConfigWarningModalComponent } from '@app/modal/instance-config-
import { ServerConfig, UserRole } from '@shared/models'
import { User } from '@app/shared'
import { InstanceService } from '@app/shared/instance/instance.service'
import { MenuService } from './core/menu/menu.service'
@Component({
selector: 'my-app',
@ -28,9 +29,6 @@ export class AppComponent implements OnInit {
@ViewChild('welcomeModal') welcomeModal: WelcomeModalComponent
@ViewChild('instanceConfigWarningModal') instanceConfigWarningModal: InstanceConfigWarningModalComponent
isMenuDisplayed = true
isMenuChangedByUser = false
customCSS: SafeHtml
private serverConfig: ServerConfig
@ -50,7 +48,8 @@ export class AppComponent implements OnInit {
private themeService: ThemeService,
private hooks: HooksService,
private location: PlatformLocation,
private modalService: NgbModal
private modalService: NgbModal,
public menu: MenuService
) { }
get instanceName () {
@ -78,21 +77,12 @@ export class AppComponent implements OnInit {
this.authService.refreshUserInformation()
}
// Do not display menu on small screens
if (this.screenService.isInSmallView()) {
this.isMenuDisplayed = false
}
this.initRouteEvents()
this.injectJS()
this.injectCSS()
this.initHotkeys()
fromEvent(window, 'resize')
.pipe(debounceTime(200))
.subscribe(() => this.onResize())
this.location.onPopState(() => this.modalService.dismissAll(POP_STATE_MODAL_DISMISS))
this.openModalsIfNeeded()
@ -102,15 +92,6 @@ export class AppComponent implements OnInit {
return this.authService.isLoggedIn()
}
toggleMenu () {
this.isMenuDisplayed = !this.isMenuDisplayed
this.isMenuChangedByUser = true
}
onResize () {
this.isMenuDisplayed = window.innerWidth >= 800 && !this.isMenuChangedByUser
}
private initRouteEvents () {
let resetScroll = true
const eventsObs = this.router.events
@ -176,7 +157,7 @@ export class AppComponent implements OnInit {
eventsObs.pipe(
filter((e: Event): e is GuardsCheckStart => e instanceof GuardsCheckStart),
filter(() => this.screenService.isInSmallView())
).subscribe(() => this.isMenuDisplayed = false) // User clicked on a link in the menu, change the page
).subscribe(() => this.menu.isMenuDisplayed = false) // User clicked on a link in the menu, change the page
}
private injectJS () {
@ -249,7 +230,7 @@ export class AppComponent implements OnInit {
}, undefined, this.i18n('Focus the search bar')),
new Hotkey('b', (event: KeyboardEvent): boolean => {
this.toggleMenu()
this.menu.toggleMenu()
return false
}, undefined, this.i18n('Toggle the left menu')),

View File

@ -13,6 +13,7 @@ import { throwIfAlreadyLoaded } from './module-import-guard'
import { LoginGuard, RedirectService, UserRightGuard } from './routing'
import { ServerService } from './server'
import { ThemeService } from './theme'
import { MenuService } from './menu'
import { HotkeyModule } from 'angular2-hotkeys'
import { CheatSheetComponent } from './hotkeys'
import { ToastModule } from 'primeng/toast'
@ -59,6 +60,7 @@ import { HooksService } from '@app/core/plugins/hooks.service'
ConfirmService,
ServerService,
ThemeService,
MenuService,
LoginGuard,
UserRightGuard,
UnloggedGuard,

View File

@ -0,0 +1 @@
export * from './menu.service'

View File

@ -0,0 +1,32 @@
import { Injectable } from '@angular/core'
import { ScreenService } from '@app/shared/misc/screen.service'
import { fromEvent } from 'rxjs'
import { debounceTime } from 'rxjs/operators'
@Injectable()
export class MenuService {
isMenuDisplayed = true
isMenuChangedByUser = false
constructor(
private screenService: ScreenService
) {
// Do not display menu on small screens
if (this.screenService.isInSmallView()) {
this.isMenuDisplayed = false
}
fromEvent(window, 'resize')
.pipe(debounceTime(200))
.subscribe(() => this.onResize())
}
toggleMenu () {
this.isMenuDisplayed = !this.isMenuDisplayed
this.isMenuChangedByUser = true
}
onResize () {
this.isMenuDisplayed = window.innerWidth >= 800 && !this.isMenuChangedByUser
}
}

View File

@ -2,3 +2,4 @@ export * from './login-guard.service'
export * from './user-right-guard.service'
export * from './preload-selected-modules-list'
export * from './redirect.service'
export * from './menu-guard.service'

View File

@ -0,0 +1,48 @@
import { Injectable } from '@angular/core'
import { CanActivate, CanDeactivate } from '@angular/router'
import { MenuService } from '@app/core/menu'
import { ScreenService } from '@app/shared/misc/screen.service'
abstract class MenuGuard implements CanActivate, CanDeactivate<any> {
display = true
canDeactivate = this.canActivate
constructor (protected menu: MenuService, protected screen: ScreenService, display: boolean) {
this.display = display
}
canActivate (): boolean {
// small screens already have the site-wide onResize from screenService
// > medium screens have enough space to fit the administrative menus
if (!this.screen.isInMobileView() && this.screen.isInMediumView()) {
this.menu.isMenuDisplayed = this.display
}
return true
}
}
@Injectable()
export class OpenMenuGuard extends MenuGuard {
constructor (menu: MenuService, screen: ScreenService) { super(menu, screen, true) }
}
@Injectable()
export class CloseMenuGuard extends MenuGuard {
constructor (menu: MenuService, screen: ScreenService) { super(menu, screen, false) }
}
@Injectable()
export class MenuGuards {
public static guards = [
OpenMenuGuard,
CloseMenuGuard
]
static open () {
return OpenMenuGuard
}
static close () {
return CloseMenuGuard
}
}

View File

@ -8,7 +8,6 @@ import { first } from 'rxjs/operators'
import { User } from '@app/shared/users/user.model'
import { UserService } from '@app/shared/users/user.service'
import { LocalStorageService } from '@app/shared/misc/storage.service'
import { peertubeLocalStorage } from '@app/shared/misc/peertube-web-storage'
@Injectable()
export class ThemeService {

View File

@ -14,6 +14,10 @@ export class ScreenService {
return this.getWindowInnerWidth() < 800
}
isInMediumView () {
return this.getWindowInnerWidth() < 1100
}
isInMobileView () {
return this.getWindowInnerWidth() < 500
}