aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorKim <1877318+kimsible@users.noreply.github.com>2020-04-30 19:23:54 +0200
committerGitHub <noreply@github.com>2020-04-30 19:23:54 +0200
commitd363ef5360b479d5f494ac1559fba59b2069fe9e (patch)
tree25aaf8505f9d3e826f4a1242f69abc497a074005
parentc285180a45e6cd342184512cae2bb56af51fe833 (diff)
downloadPeerTube-d363ef5360b479d5f494ac1559fba59b2069fe9e.tar.gz
PeerTube-d363ef5360b479d5f494ac1559fba59b2069fe9e.tar.zst
PeerTube-d363ef5360b479d5f494ac1559fba59b2069fe9e.zip
Use modal instead of dropdown menu in small/mobile views (#2674)
Co-Authored-By: Rigel Kent <par@rigelk.eu>
-rw-r--r--client/src/app/shared/menu/top-menu-dropdown.component.html33
-rw-r--r--client/src/app/shared/menu/top-menu-dropdown.component.scss29
-rw-r--r--client/src/app/shared/menu/top-menu-dropdown.component.ts50
3 files changed, 101 insertions, 11 deletions
diff --git a/client/src/app/shared/menu/top-menu-dropdown.component.html b/client/src/app/shared/menu/top-menu-dropdown.component.html
index 3087b2e98..d577f757d 100644
--- a/client/src/app/shared/menu/top-menu-dropdown.component.html
+++ b/client/src/app/shared/menu/top-menu-dropdown.component.html
@@ -1,10 +1,20 @@
1<div class="sub-menu"> 1<div class="sub-menu" [ngClass]="{ 'no-scroll': isModalOpened }">
2 <ng-container *ngFor="let menuEntry of menuEntries"> 2 <ng-container *ngFor="let menuEntry of menuEntries; index as id">
3 3
4 <a *ngIf="menuEntry.routerLink" [routerLink]="menuEntry.routerLink" routerLinkActive="active" class="title-page title-page-settings">{{ menuEntry.label }}</a> 4 <a *ngIf="menuEntry.routerLink" [routerLink]="menuEntry.routerLink" routerLinkActive="active" class="title-page title-page-settings">{{ menuEntry.label }}</a>
5 5
6 <div *ngIf="!menuEntry.routerLink" ngbDropdown [container]="container" class="parent-entry" #dropdown="ngbDropdown" (mouseleave)="closeDropdownIfHovered(dropdown)"> 6 <div *ngIf="!menuEntry.routerLink" ngbDropdown [container]="container" class="parent-entry"
7 #dropdown="ngbDropdown" (mouseleave)="closeDropdownIfHovered(dropdown)">
7 <span 8 <span
9 *ngIf="isInSmallView"
10 [ngClass]="{ active: !!suffixLabels[menuEntry.label] }"
11 (click)="openModal(id)" role="button" class="title-page title-page-settings">
12 <ng-container i18n>{{ menuEntry.label }}</ng-container>
13 <ng-container *ngIf="!!suffixLabels[menuEntry.label]"> - {{ suffixLabels[menuEntry.label] }}</ng-container>
14 </span>
15
16 <span
17 *ngIf="!isInSmallView"
8 (mouseenter)="openDropdownOnHover(dropdown)" [ngClass]="{ active: !!suffixLabels[menuEntry.label] }" ngbDropdownAnchor 18 (mouseenter)="openDropdownOnHover(dropdown)" [ngClass]="{ active: !!suffixLabels[menuEntry.label] }" ngbDropdownAnchor
9 (click)="dropdownAnchorClicked(dropdown)" role="button" class="title-page title-page-settings" 19 (click)="dropdownAnchorClicked(dropdown)" role="button" class="title-page title-page-settings"
10 > 20 >
@@ -20,6 +30,21 @@
20 </a> 30 </a>
21 </div> 31 </div>
22 </div> 32 </div>
23
24 </ng-container> 33 </ng-container>
25</div> 34</div>
35
36<ng-template #modal let-close="close" let-dismiss="dismiss">
37 <div class="modal-body">
38 <ng-container *ngFor="let menuEntry of menuEntries; index as id">
39 <div [ngClass]="{ hidden: id !== currentMenuEntryIndex }">
40 <a *ngFor="let menuChild of menuEntry.children"
41 [ngClass]="{ icon: hasIcons }"
42 [routerLink]="menuChild.routerLink" routerLinkActive="active" (click)="dismissOtherModals()">
43 <my-global-icon *ngIf="menuChild.iconName" [iconName]="menuChild.iconName"></my-global-icon>
44
45 {{ menuChild.label }}
46 </a>
47 </div>
48 </ng-container>
49 </div>
50</ng-template>
diff --git a/client/src/app/shared/menu/top-menu-dropdown.component.scss b/client/src/app/shared/menu/top-menu-dropdown.component.scss
index 1be699a88..5f90dcf80 100644
--- a/client/src/app/shared/menu/top-menu-dropdown.component.scss
+++ b/client/src/app/shared/menu/top-menu-dropdown.component.scss
@@ -25,3 +25,32 @@
25 25
26 top: -1px; 26 top: -1px;
27} 27}
28
29.sub-menu.no-scroll {
30 overflow-x: hidden;
31}
32
33.modal-body {
34 .hidden {
35 display: none;
36 }
37
38 a {
39 @include disable-default-a-behaviour;
40
41 color: currentColor;
42 box-sizing: border-box;
43 display: block;
44 font-size: 1.2rem;
45 padding: 9px 12px;
46 text-align: initial;
47 text-transform: unset;
48 width: 100%;
49
50 &.active {
51 color: var(--mainBackgroundColor) !important;
52 background-color: var(--mainHoverColor);
53 opacity: .9;
54 }
55 }
56}
diff --git a/client/src/app/shared/menu/top-menu-dropdown.component.ts b/client/src/app/shared/menu/top-menu-dropdown.component.ts
index 24a083654..f98240804 100644
--- a/client/src/app/shared/menu/top-menu-dropdown.component.ts
+++ b/client/src/app/shared/menu/top-menu-dropdown.component.ts
@@ -1,8 +1,14 @@
1import { Component, Input, OnDestroy, OnInit } from '@angular/core' 1import {
2 Component,
3 Input,
4 OnDestroy,
5 OnInit,
6 ViewChild
7} from '@angular/core'
2import { filter, take } from 'rxjs/operators' 8import { filter, take } from 'rxjs/operators'
3import { NavigationEnd, Router } from '@angular/router' 9import { NavigationEnd, Router } from '@angular/router'
4import { Subscription } from 'rxjs' 10import { Subscription } from 'rxjs'
5import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap' 11import { NgbDropdown, NgbModal } from '@ng-bootstrap/ng-bootstrap'
6import { GlobalIconName } from '@app/shared/images/global-icon.component' 12import { GlobalIconName } from '@app/shared/images/global-icon.component'
7import { ScreenService } from '@app/shared/misc/screen.service' 13import { ScreenService } from '@app/shared/misc/screen.service'
8 14
@@ -26,31 +32,40 @@ export type TopMenuDropdownParam = {
26export class TopMenuDropdownComponent implements OnInit, OnDestroy { 32export class TopMenuDropdownComponent implements OnInit, OnDestroy {
27 @Input() menuEntries: TopMenuDropdownParam[] = [] 33 @Input() menuEntries: TopMenuDropdownParam[] = []
28 34
35 @ViewChild('modal', { static: true }) modal: NgbModal
36
29 suffixLabels: { [ parentLabel: string ]: string } 37 suffixLabels: { [ parentLabel: string ]: string }
30 hasIcons = false 38 hasIcons = false
31 container: undefined | 'body' = undefined 39 container: undefined | 'body' = undefined
40 isModalOpened = false
41 currentMenuEntryIndex: number
32 42
33 private openedOnHover = false 43 private openedOnHover = false
34 private routeSub: Subscription 44 private routeSub: Subscription
35 45
36 constructor ( 46 constructor (
37 private router: Router, 47 private router: Router,
48 private modalService: NgbModal,
38 private screen: ScreenService 49 private screen: ScreenService
39 ) {} 50 ) { }
51
52 get isInSmallView () {
53 return this.screen.isInSmallView()
54 }
40 55
41 ngOnInit () { 56 ngOnInit () {
42 this.updateChildLabels(window.location.pathname) 57 this.updateChildLabels(window.location.pathname)
43 58
44 this.routeSub = this.router.events 59 this.routeSub = this.router.events
45 .pipe(filter(event => event instanceof NavigationEnd)) 60 .pipe(filter(event => event instanceof NavigationEnd))
46 .subscribe(() => this.updateChildLabels(window.location.pathname)) 61 .subscribe(() => this.updateChildLabels(window.location.pathname))
47 62
48 this.hasIcons = this.menuEntries.some( 63 this.hasIcons = this.menuEntries.some(
49 e => e.children && e.children.some(c => !!c.iconName) 64 e => e.children && e.children.some(c => !!c.iconName)
50 ) 65 )
51 66
52 // We have to set body for the container to avoid scroll overflow on mobile view 67 // We have to set body for the container to avoid scroll overflow on mobile and small views
53 if (this.screen.isInMobileView()) { 68 if (this.isInSmallView) {
54 this.container = 'body' 69 this.container = 'body'
55 } 70 }
56 } 71 }
@@ -85,6 +100,27 @@ export class TopMenuDropdownComponent implements OnInit, OnDestroy {
85 this.openedOnHover = false 100 this.openedOnHover = false
86 } 101 }
87 102
103 openModal (index: number) {
104 this.currentMenuEntryIndex = index
105 this.isModalOpened = true
106
107 this.modalService.open(this.modal, {
108 centered: true,
109 beforeDismiss: async () => {
110 this.onModalDismiss()
111 return true
112 }
113 })
114 }
115
116 onModalDismiss () {
117 this.isModalOpened = false
118 }
119
120 dismissOtherModals () {
121 this.modalService.dismissAll()
122 }
123
88 private updateChildLabels (path: string) { 124 private updateChildLabels (path: string) {
89 this.suffixLabels = {} 125 this.suffixLabels = {}
90 126