diff options
author | Rigel Kent <sendmemail@rigelk.eu> | 2020-03-07 13:50:26 +0100 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2020-03-10 16:22:52 +0100 |
commit | 3b20bdd6dc7402b0723e038c57f0606131e20e54 (patch) | |
tree | 68b203892c15c524f57651bfda7e6d5c0e920443 | |
parent | 7b81edc854902a536083298472bf92bb6726edcf (diff) | |
download | PeerTube-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.ts | 4 | ||||
-rw-r--r-- | client/src/app/app.component.html | 10 | ||||
-rw-r--r-- | client/src/app/app.component.ts | 29 | ||||
-rw-r--r-- | client/src/app/core/core.module.ts | 2 | ||||
-rw-r--r-- | client/src/app/core/menu/index.ts | 1 | ||||
-rw-r--r-- | client/src/app/core/menu/menu.service.ts | 32 | ||||
-rw-r--r-- | client/src/app/core/routing/index.ts | 1 | ||||
-rw-r--r-- | client/src/app/core/routing/menu-guard.service.ts | 48 | ||||
-rw-r--r-- | client/src/app/core/theme/theme.service.ts | 1 | ||||
-rw-r--r-- | client/src/app/shared/misc/screen.service.ts | 4 |
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' | |||
4 | import { PreloadSelectedModulesList } from './core' | 4 | import { PreloadSelectedModulesList } from './core' |
5 | import { AppComponent } from '@app/app.component' | 5 | import { AppComponent } from '@app/app.component' |
6 | import { CustomReuseStrategy } from '@app/core/routing/custom-reuse-strategy' | 6 | import { CustomReuseStrategy } from '@app/core/routing/custom-reuse-strategy' |
7 | import { MenuGuards } from '@app/core/routing/menu-guard.service' | ||
7 | 8 | ||
8 | const routes: Routes = [ | 9 | const 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- | |||
18 | import { ServerConfig, UserRole } from '@shared/models' | 18 | import { ServerConfig, UserRole } from '@shared/models' |
19 | import { User } from '@app/shared' | 19 | import { User } from '@app/shared' |
20 | import { InstanceService } from '@app/shared/instance/instance.service' | 20 | import { InstanceService } from '@app/shared/instance/instance.service' |
21 | import { 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' | |||
13 | import { LoginGuard, RedirectService, UserRightGuard } from './routing' | 13 | import { LoginGuard, RedirectService, UserRightGuard } from './routing' |
14 | import { ServerService } from './server' | 14 | import { ServerService } from './server' |
15 | import { ThemeService } from './theme' | 15 | import { ThemeService } from './theme' |
16 | import { MenuService } from './menu' | ||
16 | import { HotkeyModule } from 'angular2-hotkeys' | 17 | import { HotkeyModule } from 'angular2-hotkeys' |
17 | import { CheatSheetComponent } from './hotkeys' | 18 | import { CheatSheetComponent } from './hotkeys' |
18 | import { ToastModule } from 'primeng/toast' | 19 | import { 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 @@ | |||
1 | import { Injectable } from '@angular/core' | ||
2 | import { ScreenService } from '@app/shared/misc/screen.service' | ||
3 | import { fromEvent } from 'rxjs' | ||
4 | import { debounceTime } from 'rxjs/operators' | ||
5 | |||
6 | @Injectable() | ||
7 | export 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' | |||
2 | export * from './user-right-guard.service' | 2 | export * from './user-right-guard.service' |
3 | export * from './preload-selected-modules-list' | 3 | export * from './preload-selected-modules-list' |
4 | export * from './redirect.service' | 4 | export * from './redirect.service' |
5 | export * 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 @@ | |||
1 | import { Injectable } from '@angular/core' | ||
2 | import { CanActivate, CanDeactivate } from '@angular/router' | ||
3 | import { MenuService } from '@app/core/menu' | ||
4 | import { ScreenService } from '@app/shared/misc/screen.service' | ||
5 | |||
6 | abstract 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() | ||
25 | export class OpenMenuGuard extends MenuGuard { | ||
26 | constructor (menu: MenuService, screen: ScreenService) { super(menu, screen, true) } | ||
27 | } | ||
28 | |||
29 | @Injectable() | ||
30 | export class CloseMenuGuard extends MenuGuard { | ||
31 | constructor (menu: MenuService, screen: ScreenService) { super(menu, screen, false) } | ||
32 | } | ||
33 | |||
34 | @Injectable() | ||
35 | export 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' | |||
8 | import { User } from '@app/shared/users/user.model' | 8 | import { User } from '@app/shared/users/user.model' |
9 | import { UserService } from '@app/shared/users/user.service' | 9 | import { UserService } from '@app/shared/users/user.service' |
10 | import { LocalStorageService } from '@app/shared/misc/storage.service' | 10 | import { LocalStorageService } from '@app/shared/misc/storage.service' |
11 | import { peertubeLocalStorage } from '@app/shared/misc/peertube-web-storage' | ||
12 | 11 | ||
13 | @Injectable() | 12 | @Injectable() |
14 | export class ThemeService { | 13 | export 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 | } |