aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRigel Kent <sendmemail@rigelk.eu>2020-03-07 13:50:26 +0100
committerChocobozzz <chocobozzz@cpy.re>2020-03-10 16:22:52 +0100
commit3b20bdd6dc7402b0723e038c57f0606131e20e54 (patch)
tree68b203892c15c524f57651bfda7e6d5c0e920443
parent7b81edc854902a536083298472bf92bb6726edcf (diff)
downloadPeerTube-3b20bdd6dc7402b0723e038c57f0606131e20e54.tar.gz
PeerTube-3b20bdd6dc7402b0723e038c57f0606131e20e54.tar.zst
PeerTube-3b20bdd6dc7402b0723e038c57f0606131e20e54.zip
Servicify menu, close menu on admin for small and medium screens
-rw-r--r--client/src/app/app-routing.module.ts4
-rw-r--r--client/src/app/app.component.html10
-rw-r--r--client/src/app/app.component.ts29
-rw-r--r--client/src/app/core/core.module.ts2
-rw-r--r--client/src/app/core/menu/index.ts1
-rw-r--r--client/src/app/core/menu/menu.service.ts32
-rw-r--r--client/src/app/core/routing/index.ts1
-rw-r--r--client/src/app/core/routing/menu-guard.service.ts48
-rw-r--r--client/src/app/core/theme/theme.service.ts1
-rw-r--r--client/src/app/shared/misc/screen.service.ts4
10 files changed, 102 insertions, 30 deletions
diff --git a/client/src/app/app-routing.module.ts b/client/src/app/app-routing.module.ts
index b5a677d15..a87f4ce1b 100644
--- a/client/src/app/app-routing.module.ts
+++ b/client/src/app/app-routing.module.ts
@@ -4,10 +4,13 @@ import { RouteReuseStrategy, RouterModule, Routes } from '@angular/router'
4import { PreloadSelectedModulesList } from './core' 4import { PreloadSelectedModulesList } from './core'
5import { AppComponent } from '@app/app.component' 5import { AppComponent } from '@app/app.component'
6import { CustomReuseStrategy } from '@app/core/routing/custom-reuse-strategy' 6import { CustomReuseStrategy } from '@app/core/routing/custom-reuse-strategy'
7import { MenuGuards } from '@app/core/routing/menu-guard.service'
7 8
8const routes: Routes = [ 9const routes: Routes = [
9 { 10 {
10 path: 'admin', 11 path: 'admin',
12 canActivate: [ MenuGuards.close() ],
13 canDeactivate: [ MenuGuards.open() ],
11 loadChildren: () => import('./+admin/admin.module').then(m => m.AdminModule) 14 loadChildren: () => import('./+admin/admin.module').then(m => m.AdminModule)
12 }, 15 },
13 { 16 {
@@ -54,6 +57,7 @@ const routes: Routes = [
54 }) 57 })
55 ], 58 ],
56 providers: [ 59 providers: [
60 MenuGuards.guards,
57 PreloadSelectedModulesList, 61 PreloadSelectedModulesList,
58 { provide: RouteReuseStrategy, useClass: CustomReuseStrategy } 62 { provide: RouteReuseStrategy, useClass: CustomReuseStrategy }
59 ], 63 ],
diff --git a/client/src/app/app.component.html b/client/src/app/app.component.html
index 54b320f79..d5fec61e6 100644
--- a/client/src/app/app.component.html
+++ b/client/src/app/app.component.html
@@ -5,8 +5,8 @@
5<div [ngClass]="{ 'user-logged-in': isUserLoggedIn(), 'user-not-logged-in': !isUserLoggedIn() }"> 5<div [ngClass]="{ 'user-logged-in': isUserLoggedIn(), 'user-not-logged-in': !isUserLoggedIn() }">
6 <div class="header"> 6 <div class="header">
7 7
8 <div class="top-left-block" [ngClass]="{ 'border-bottom': isMenuDisplayed === false }"> 8 <div class="top-left-block" [ngClass]="{ 'border-bottom': menu.isMenuDisplayed === false }">
9 <span class="icon icon-menu" (click)="toggleMenu()"></span> 9 <span class="icon icon-menu" (click)="menu.toggleMenu()"></span>
10 10
11 <a class="peertube-title" [routerLink]="defaultRoute" title="Homepage" i18n-title> 11 <a class="peertube-title" [routerLink]="defaultRoute" title="Homepage" i18n-title>
12 <span class="icon icon-logo"></span> 12 <span class="icon icon-logo"></span>
@@ -14,15 +14,15 @@
14 </a> 14 </a>
15 </div> 15 </div>
16 16
17 <div class="header-right" [ngClass]="{ 'border-bottom': isMenuDisplayed === false }"> 17 <div class="header-right" [ngClass]="{ 'border-bottom': menu.isMenuDisplayed === false }">
18 <my-header class="w-100 d-flex justify-content-end"></my-header> 18 <my-header class="w-100 d-flex justify-content-end"></my-header>
19 </div> 19 </div>
20 </div> 20 </div>
21 21
22 <div class="sub-header-container"> 22 <div class="sub-header-container">
23 <my-menu *ngIf="isMenuDisplayed"></my-menu> 23 <my-menu *ngIf="menu.isMenuDisplayed"></my-menu>
24 24
25 <div id="content" tabindex="-1" class="main-col container-fluid" [ngClass]="{ expanded: isMenuDisplayed === false }"> 25 <div id="content" tabindex="-1" class="main-col container-fluid" [ngClass]="{ expanded: menu.isMenuDisplayed === false }">
26 26
27 <div class="main-row"> 27 <div class="main-row">
28 <router-outlet></router-outlet> 28 <router-outlet></router-outlet>
diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts
index 59966243b..629549ef2 100644
--- a/client/src/app/app.component.ts
+++ b/client/src/app/app.component.ts
@@ -18,6 +18,7 @@ import { InstanceConfigWarningModalComponent } from '@app/modal/instance-config-
18import { ServerConfig, UserRole } from '@shared/models' 18import { ServerConfig, UserRole } from '@shared/models'
19import { User } from '@app/shared' 19import { User } from '@app/shared'
20import { InstanceService } from '@app/shared/instance/instance.service' 20import { InstanceService } from '@app/shared/instance/instance.service'
21import { MenuService } from './core/menu/menu.service'
21 22
22@Component({ 23@Component({
23 selector: 'my-app', 24 selector: 'my-app',
@@ -28,9 +29,6 @@ export class AppComponent implements OnInit {
28 @ViewChild('welcomeModal') welcomeModal: WelcomeModalComponent 29 @ViewChild('welcomeModal') welcomeModal: WelcomeModalComponent
29 @ViewChild('instanceConfigWarningModal') instanceConfigWarningModal: InstanceConfigWarningModalComponent 30 @ViewChild('instanceConfigWarningModal') instanceConfigWarningModal: InstanceConfigWarningModalComponent
30 31
31 isMenuDisplayed = true
32 isMenuChangedByUser = false
33
34 customCSS: SafeHtml 32 customCSS: SafeHtml
35 33
36 private serverConfig: ServerConfig 34 private serverConfig: ServerConfig
@@ -50,7 +48,8 @@ export class AppComponent implements OnInit {
50 private themeService: ThemeService, 48 private themeService: ThemeService,
51 private hooks: HooksService, 49 private hooks: HooksService,
52 private location: PlatformLocation, 50 private location: PlatformLocation,
53 private modalService: NgbModal 51 private modalService: NgbModal,
52 public menu: MenuService
54 ) { } 53 ) { }
55 54
56 get instanceName () { 55 get instanceName () {
@@ -78,21 +77,12 @@ export class AppComponent implements OnInit {
78 this.authService.refreshUserInformation() 77 this.authService.refreshUserInformation()
79 } 78 }
80 79
81 // Do not display menu on small screens
82 if (this.screenService.isInSmallView()) {
83 this.isMenuDisplayed = false
84 }
85
86 this.initRouteEvents() 80 this.initRouteEvents()
87 this.injectJS() 81 this.injectJS()
88 this.injectCSS() 82 this.injectCSS()
89 83
90 this.initHotkeys() 84 this.initHotkeys()
91 85
92 fromEvent(window, 'resize')
93 .pipe(debounceTime(200))
94 .subscribe(() => this.onResize())
95
96 this.location.onPopState(() => this.modalService.dismissAll(POP_STATE_MODAL_DISMISS)) 86 this.location.onPopState(() => this.modalService.dismissAll(POP_STATE_MODAL_DISMISS))
97 87
98 this.openModalsIfNeeded() 88 this.openModalsIfNeeded()
@@ -102,15 +92,6 @@ export class AppComponent implements OnInit {
102 return this.authService.isLoggedIn() 92 return this.authService.isLoggedIn()
103 } 93 }
104 94
105 toggleMenu () {
106 this.isMenuDisplayed = !this.isMenuDisplayed
107 this.isMenuChangedByUser = true
108 }
109
110 onResize () {
111 this.isMenuDisplayed = window.innerWidth >= 800 && !this.isMenuChangedByUser
112 }
113
114 private initRouteEvents () { 95 private initRouteEvents () {
115 let resetScroll = true 96 let resetScroll = true
116 const eventsObs = this.router.events 97 const eventsObs = this.router.events
@@ -176,7 +157,7 @@ export class AppComponent implements OnInit {
176 eventsObs.pipe( 157 eventsObs.pipe(
177 filter((e: Event): e is GuardsCheckStart => e instanceof GuardsCheckStart), 158 filter((e: Event): e is GuardsCheckStart => e instanceof GuardsCheckStart),
178 filter(() => this.screenService.isInSmallView()) 159 filter(() => this.screenService.isInSmallView())
179 ).subscribe(() => this.isMenuDisplayed = false) // User clicked on a link in the menu, change the page 160 ).subscribe(() => this.menu.isMenuDisplayed = false) // User clicked on a link in the menu, change the page
180 } 161 }
181 162
182 private injectJS () { 163 private injectJS () {
@@ -249,7 +230,7 @@ export class AppComponent implements OnInit {
249 }, undefined, this.i18n('Focus the search bar')), 230 }, undefined, this.i18n('Focus the search bar')),
250 231
251 new Hotkey('b', (event: KeyboardEvent): boolean => { 232 new Hotkey('b', (event: KeyboardEvent): boolean => {
252 this.toggleMenu() 233 this.menu.toggleMenu()
253 return false 234 return false
254 }, undefined, this.i18n('Toggle the left menu')), 235 }, undefined, this.i18n('Toggle the left menu')),
255 236
diff --git a/client/src/app/core/core.module.ts b/client/src/app/core/core.module.ts
index 5943af4da..a1734ad80 100644
--- a/client/src/app/core/core.module.ts
+++ b/client/src/app/core/core.module.ts
@@ -13,6 +13,7 @@ import { throwIfAlreadyLoaded } from './module-import-guard'
13import { LoginGuard, RedirectService, UserRightGuard } from './routing' 13import { LoginGuard, RedirectService, UserRightGuard } from './routing'
14import { ServerService } from './server' 14import { ServerService } from './server'
15import { ThemeService } from './theme' 15import { ThemeService } from './theme'
16import { MenuService } from './menu'
16import { HotkeyModule } from 'angular2-hotkeys' 17import { HotkeyModule } from 'angular2-hotkeys'
17import { CheatSheetComponent } from './hotkeys' 18import { CheatSheetComponent } from './hotkeys'
18import { ToastModule } from 'primeng/toast' 19import { ToastModule } from 'primeng/toast'
@@ -59,6 +60,7 @@ import { HooksService } from '@app/core/plugins/hooks.service'
59 ConfirmService, 60 ConfirmService,
60 ServerService, 61 ServerService,
61 ThemeService, 62 ThemeService,
63 MenuService,
62 LoginGuard, 64 LoginGuard,
63 UserRightGuard, 65 UserRightGuard,
64 UnloggedGuard, 66 UnloggedGuard,
diff --git a/client/src/app/core/menu/index.ts b/client/src/app/core/menu/index.ts
new file mode 100644
index 000000000..516a49aca
--- /dev/null
+++ b/client/src/app/core/menu/index.ts
@@ -0,0 +1 @@
export * from './menu.service'
diff --git a/client/src/app/core/menu/menu.service.ts b/client/src/app/core/menu/menu.service.ts
new file mode 100644
index 000000000..46ef72e17
--- /dev/null
+++ b/client/src/app/core/menu/menu.service.ts
@@ -0,0 +1,32 @@
1import { Injectable } from '@angular/core'
2import { ScreenService } from '@app/shared/misc/screen.service'
3import { fromEvent } from 'rxjs'
4import { debounceTime } from 'rxjs/operators'
5
6@Injectable()
7export class MenuService {
8 isMenuDisplayed = true
9 isMenuChangedByUser = false
10
11 constructor(
12 private screenService: ScreenService
13 ) {
14 // Do not display menu on small screens
15 if (this.screenService.isInSmallView()) {
16 this.isMenuDisplayed = false
17 }
18
19 fromEvent(window, 'resize')
20 .pipe(debounceTime(200))
21 .subscribe(() => this.onResize())
22 }
23
24 toggleMenu () {
25 this.isMenuDisplayed = !this.isMenuDisplayed
26 this.isMenuChangedByUser = true
27 }
28
29 onResize () {
30 this.isMenuDisplayed = window.innerWidth >= 800 && !this.isMenuChangedByUser
31 }
32}
diff --git a/client/src/app/core/routing/index.ts b/client/src/app/core/routing/index.ts
index 9f0b4eac5..58b83bb2a 100644
--- a/client/src/app/core/routing/index.ts
+++ b/client/src/app/core/routing/index.ts
@@ -2,3 +2,4 @@ export * from './login-guard.service'
2export * from './user-right-guard.service' 2export * from './user-right-guard.service'
3export * from './preload-selected-modules-list' 3export * from './preload-selected-modules-list'
4export * from './redirect.service' 4export * from './redirect.service'
5export * from './menu-guard.service'
diff --git a/client/src/app/core/routing/menu-guard.service.ts b/client/src/app/core/routing/menu-guard.service.ts
new file mode 100644
index 000000000..907d145fd
--- /dev/null
+++ b/client/src/app/core/routing/menu-guard.service.ts
@@ -0,0 +1,48 @@
1import { Injectable } from '@angular/core'
2import { CanActivate, CanDeactivate } from '@angular/router'
3import { MenuService } from '@app/core/menu'
4import { ScreenService } from '@app/shared/misc/screen.service'
5
6abstract class MenuGuard implements CanActivate, CanDeactivate<any> {
7 display = true
8 canDeactivate = this.canActivate
9
10 constructor (protected menu: MenuService, protected screen: ScreenService, display: boolean) {
11 this.display = display
12 }
13
14 canActivate (): boolean {
15 // small screens already have the site-wide onResize from screenService
16 // > medium screens have enough space to fit the administrative menus
17 if (!this.screen.isInMobileView() && this.screen.isInMediumView()) {
18 this.menu.isMenuDisplayed = this.display
19 }
20 return true
21 }
22}
23
24@Injectable()
25export class OpenMenuGuard extends MenuGuard {
26 constructor (menu: MenuService, screen: ScreenService) { super(menu, screen, true) }
27}
28
29@Injectable()
30export class CloseMenuGuard extends MenuGuard {
31 constructor (menu: MenuService, screen: ScreenService) { super(menu, screen, false) }
32}
33
34@Injectable()
35export class MenuGuards {
36 public static guards = [
37 OpenMenuGuard,
38 CloseMenuGuard
39 ]
40
41 static open () {
42 return OpenMenuGuard
43 }
44
45 static close () {
46 return CloseMenuGuard
47 }
48}
diff --git a/client/src/app/core/theme/theme.service.ts b/client/src/app/core/theme/theme.service.ts
index 3c066ca74..c0189ad32 100644
--- a/client/src/app/core/theme/theme.service.ts
+++ b/client/src/app/core/theme/theme.service.ts
@@ -8,7 +8,6 @@ import { first } from 'rxjs/operators'
8import { User } from '@app/shared/users/user.model' 8import { User } from '@app/shared/users/user.model'
9import { UserService } from '@app/shared/users/user.service' 9import { UserService } from '@app/shared/users/user.service'
10import { LocalStorageService } from '@app/shared/misc/storage.service' 10import { LocalStorageService } from '@app/shared/misc/storage.service'
11import { peertubeLocalStorage } from '@app/shared/misc/peertube-web-storage'
12 11
13@Injectable() 12@Injectable()
14export class ThemeService { 13export class ThemeService {
diff --git a/client/src/app/shared/misc/screen.service.ts b/client/src/app/shared/misc/screen.service.ts
index 220d41d59..9c71a8c83 100644
--- a/client/src/app/shared/misc/screen.service.ts
+++ b/client/src/app/shared/misc/screen.service.ts
@@ -14,6 +14,10 @@ export class ScreenService {
14 return this.getWindowInnerWidth() < 800 14 return this.getWindowInnerWidth() < 800
15 } 15 }
16 16
17 isInMediumView () {
18 return this.getWindowInnerWidth() < 1100
19 }
20
17 isInMobileView () { 21 isInMobileView () {
18 return this.getWindowInnerWidth() < 500 22 return this.getWindowInnerWidth() < 500
19 } 23 }