Servicify menu, close menu on admin for small and medium screens
This commit is contained in:
parent
7b81edc854
commit
3b20bdd6dc
|
@ -4,10 +4,13 @@ import { RouteReuseStrategy, RouterModule, Routes } from '@angular/router'
|
||||||
import { PreloadSelectedModulesList } from './core'
|
import { PreloadSelectedModulesList } from './core'
|
||||||
import { AppComponent } from '@app/app.component'
|
import { AppComponent } from '@app/app.component'
|
||||||
import { CustomReuseStrategy } from '@app/core/routing/custom-reuse-strategy'
|
import { CustomReuseStrategy } from '@app/core/routing/custom-reuse-strategy'
|
||||||
|
import { MenuGuards } from '@app/core/routing/menu-guard.service'
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: 'admin',
|
path: 'admin',
|
||||||
|
canActivate: [ MenuGuards.close() ],
|
||||||
|
canDeactivate: [ MenuGuards.open() ],
|
||||||
loadChildren: () => import('./+admin/admin.module').then(m => m.AdminModule)
|
loadChildren: () => import('./+admin/admin.module').then(m => m.AdminModule)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -54,6 +57,7 @@ const routes: Routes = [
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
|
MenuGuards.guards,
|
||||||
PreloadSelectedModulesList,
|
PreloadSelectedModulesList,
|
||||||
{ provide: RouteReuseStrategy, useClass: CustomReuseStrategy }
|
{ provide: RouteReuseStrategy, useClass: CustomReuseStrategy }
|
||||||
],
|
],
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
<div [ngClass]="{ 'user-logged-in': isUserLoggedIn(), 'user-not-logged-in': !isUserLoggedIn() }">
|
<div [ngClass]="{ 'user-logged-in': isUserLoggedIn(), 'user-not-logged-in': !isUserLoggedIn() }">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
|
|
||||||
<div class="top-left-block" [ngClass]="{ 'border-bottom': isMenuDisplayed === false }">
|
<div class="top-left-block" [ngClass]="{ 'border-bottom': menu.isMenuDisplayed === false }">
|
||||||
<span class="icon icon-menu" (click)="toggleMenu()"></span>
|
<span class="icon icon-menu" (click)="menu.toggleMenu()"></span>
|
||||||
|
|
||||||
<a class="peertube-title" [routerLink]="defaultRoute" title="Homepage" i18n-title>
|
<a class="peertube-title" [routerLink]="defaultRoute" title="Homepage" i18n-title>
|
||||||
<span class="icon icon-logo"></span>
|
<span class="icon icon-logo"></span>
|
||||||
|
@ -14,15 +14,15 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</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>
|
<my-header class="w-100 d-flex justify-content-end"></my-header>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="sub-header-container">
|
<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">
|
<div class="main-row">
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { InstanceConfigWarningModalComponent } from '@app/modal/instance-config-
|
||||||
import { ServerConfig, UserRole } from '@shared/models'
|
import { ServerConfig, UserRole } from '@shared/models'
|
||||||
import { User } from '@app/shared'
|
import { User } from '@app/shared'
|
||||||
import { InstanceService } from '@app/shared/instance/instance.service'
|
import { InstanceService } from '@app/shared/instance/instance.service'
|
||||||
|
import { MenuService } from './core/menu/menu.service'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-app',
|
selector: 'my-app',
|
||||||
|
@ -28,9 +29,6 @@ export class AppComponent implements OnInit {
|
||||||
@ViewChild('welcomeModal') welcomeModal: WelcomeModalComponent
|
@ViewChild('welcomeModal') welcomeModal: WelcomeModalComponent
|
||||||
@ViewChild('instanceConfigWarningModal') instanceConfigWarningModal: InstanceConfigWarningModalComponent
|
@ViewChild('instanceConfigWarningModal') instanceConfigWarningModal: InstanceConfigWarningModalComponent
|
||||||
|
|
||||||
isMenuDisplayed = true
|
|
||||||
isMenuChangedByUser = false
|
|
||||||
|
|
||||||
customCSS: SafeHtml
|
customCSS: SafeHtml
|
||||||
|
|
||||||
private serverConfig: ServerConfig
|
private serverConfig: ServerConfig
|
||||||
|
@ -50,7 +48,8 @@ export class AppComponent implements OnInit {
|
||||||
private themeService: ThemeService,
|
private themeService: ThemeService,
|
||||||
private hooks: HooksService,
|
private hooks: HooksService,
|
||||||
private location: PlatformLocation,
|
private location: PlatformLocation,
|
||||||
private modalService: NgbModal
|
private modalService: NgbModal,
|
||||||
|
public menu: MenuService
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
get instanceName () {
|
get instanceName () {
|
||||||
|
@ -78,21 +77,12 @@ export class AppComponent implements OnInit {
|
||||||
this.authService.refreshUserInformation()
|
this.authService.refreshUserInformation()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not display menu on small screens
|
|
||||||
if (this.screenService.isInSmallView()) {
|
|
||||||
this.isMenuDisplayed = false
|
|
||||||
}
|
|
||||||
|
|
||||||
this.initRouteEvents()
|
this.initRouteEvents()
|
||||||
this.injectJS()
|
this.injectJS()
|
||||||
this.injectCSS()
|
this.injectCSS()
|
||||||
|
|
||||||
this.initHotkeys()
|
this.initHotkeys()
|
||||||
|
|
||||||
fromEvent(window, 'resize')
|
|
||||||
.pipe(debounceTime(200))
|
|
||||||
.subscribe(() => this.onResize())
|
|
||||||
|
|
||||||
this.location.onPopState(() => this.modalService.dismissAll(POP_STATE_MODAL_DISMISS))
|
this.location.onPopState(() => this.modalService.dismissAll(POP_STATE_MODAL_DISMISS))
|
||||||
|
|
||||||
this.openModalsIfNeeded()
|
this.openModalsIfNeeded()
|
||||||
|
@ -102,15 +92,6 @@ export class AppComponent implements OnInit {
|
||||||
return this.authService.isLoggedIn()
|
return this.authService.isLoggedIn()
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleMenu () {
|
|
||||||
this.isMenuDisplayed = !this.isMenuDisplayed
|
|
||||||
this.isMenuChangedByUser = true
|
|
||||||
}
|
|
||||||
|
|
||||||
onResize () {
|
|
||||||
this.isMenuDisplayed = window.innerWidth >= 800 && !this.isMenuChangedByUser
|
|
||||||
}
|
|
||||||
|
|
||||||
private initRouteEvents () {
|
private initRouteEvents () {
|
||||||
let resetScroll = true
|
let resetScroll = true
|
||||||
const eventsObs = this.router.events
|
const eventsObs = this.router.events
|
||||||
|
@ -176,7 +157,7 @@ export class AppComponent implements OnInit {
|
||||||
eventsObs.pipe(
|
eventsObs.pipe(
|
||||||
filter((e: Event): e is GuardsCheckStart => e instanceof GuardsCheckStart),
|
filter((e: Event): e is GuardsCheckStart => e instanceof GuardsCheckStart),
|
||||||
filter(() => this.screenService.isInSmallView())
|
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 () {
|
private injectJS () {
|
||||||
|
@ -249,7 +230,7 @@ export class AppComponent implements OnInit {
|
||||||
}, undefined, this.i18n('Focus the search bar')),
|
}, undefined, this.i18n('Focus the search bar')),
|
||||||
|
|
||||||
new Hotkey('b', (event: KeyboardEvent): boolean => {
|
new Hotkey('b', (event: KeyboardEvent): boolean => {
|
||||||
this.toggleMenu()
|
this.menu.toggleMenu()
|
||||||
return false
|
return false
|
||||||
}, undefined, this.i18n('Toggle the left menu')),
|
}, undefined, this.i18n('Toggle the left menu')),
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ import { throwIfAlreadyLoaded } from './module-import-guard'
|
||||||
import { LoginGuard, RedirectService, UserRightGuard } from './routing'
|
import { LoginGuard, RedirectService, UserRightGuard } from './routing'
|
||||||
import { ServerService } from './server'
|
import { ServerService } from './server'
|
||||||
import { ThemeService } from './theme'
|
import { ThemeService } from './theme'
|
||||||
|
import { MenuService } from './menu'
|
||||||
import { HotkeyModule } from 'angular2-hotkeys'
|
import { HotkeyModule } from 'angular2-hotkeys'
|
||||||
import { CheatSheetComponent } from './hotkeys'
|
import { CheatSheetComponent } from './hotkeys'
|
||||||
import { ToastModule } from 'primeng/toast'
|
import { ToastModule } from 'primeng/toast'
|
||||||
|
@ -59,6 +60,7 @@ import { HooksService } from '@app/core/plugins/hooks.service'
|
||||||
ConfirmService,
|
ConfirmService,
|
||||||
ServerService,
|
ServerService,
|
||||||
ThemeService,
|
ThemeService,
|
||||||
|
MenuService,
|
||||||
LoginGuard,
|
LoginGuard,
|
||||||
UserRightGuard,
|
UserRightGuard,
|
||||||
UnloggedGuard,
|
UnloggedGuard,
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './menu.service'
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,3 +2,4 @@ export * from './login-guard.service'
|
||||||
export * from './user-right-guard.service'
|
export * from './user-right-guard.service'
|
||||||
export * from './preload-selected-modules-list'
|
export * from './preload-selected-modules-list'
|
||||||
export * from './redirect.service'
|
export * from './redirect.service'
|
||||||
|
export * from './menu-guard.service'
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,6 @@ import { first } from 'rxjs/operators'
|
||||||
import { User } from '@app/shared/users/user.model'
|
import { User } from '@app/shared/users/user.model'
|
||||||
import { UserService } from '@app/shared/users/user.service'
|
import { UserService } from '@app/shared/users/user.service'
|
||||||
import { LocalStorageService } from '@app/shared/misc/storage.service'
|
import { LocalStorageService } from '@app/shared/misc/storage.service'
|
||||||
import { peertubeLocalStorage } from '@app/shared/misc/peertube-web-storage'
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ThemeService {
|
export class ThemeService {
|
||||||
|
|
|
@ -14,6 +14,10 @@ export class ScreenService {
|
||||||
return this.getWindowInnerWidth() < 800
|
return this.getWindowInnerWidth() < 800
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isInMediumView () {
|
||||||
|
return this.getWindowInnerWidth() < 1100
|
||||||
|
}
|
||||||
|
|
||||||
isInMobileView () {
|
isInMobileView () {
|
||||||
return this.getWindowInnerWidth() < 500
|
return this.getWindowInnerWidth() < 500
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue