aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src
diff options
context:
space:
mode:
authorRigel Kent <sendmemail@rigelk.eu>2020-02-05 20:54:37 +0100
committerChocobozzz <chocobozzz@cpy.re>2020-02-13 10:25:22 +0100
commit24e7916c6897bbb38e057cdf1a102286006be964 (patch)
tree7621dd83d532ba04b725f4feeb902ccbdb6669ff /client/src
parenteb7c7a517902eae425b05d1ca9cb7f99f76ee71f (diff)
downloadPeerTube-24e7916c6897bbb38e057cdf1a102286006be964.tar.gz
PeerTube-24e7916c6897bbb38e057cdf1a102286006be964.tar.zst
PeerTube-24e7916c6897bbb38e057cdf1a102286006be964.zip
Add ListOverflow component to prevent sub-menu overflow
Diffstat (limited to 'client/src')
-rw-r--r--client/src/app/+about/about-instance/contact-admin-modal.component.ts2
-rw-r--r--client/src/app/+accounts/accounts.component.html10
-rw-r--r--client/src/app/+accounts/accounts.component.ts8
-rw-r--r--client/src/app/+admin/admin.component.html26
-rw-r--r--client/src/app/+admin/admin.component.ts22
-rw-r--r--client/src/app/+admin/moderation/video-abuse-list/moderation-comment-modal.component.ts2
-rw-r--r--client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.ts2
-rw-r--r--client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.ts2
-rw-r--r--client/src/app/+video-channels/video-channels.component.html10
-rw-r--r--client/src/app/+video-channels/video-channels.component.ts8
-rw-r--r--client/src/app/menu/language-chooser.component.ts2
-rw-r--r--client/src/app/modal/instance-config-warning-modal.component.ts2
-rw-r--r--client/src/app/modal/welcome-modal.component.ts3
-rw-r--r--client/src/app/shared/misc/list-overflow.component.html35
-rw-r--r--client/src/app/shared/misc/list-overflow.component.scss61
-rw-r--r--client/src/app/shared/misc/list-overflow.component.ts114
-rw-r--r--client/src/app/shared/moderation/user-ban-modal.component.ts2
-rw-r--r--client/src/app/shared/shared.module.ts3
-rw-r--r--client/src/app/shared/video/modals/video-blacklist.component.ts2
-rw-r--r--client/src/app/shared/video/modals/video-download.component.ts2
-rw-r--r--client/src/app/shared/video/modals/video-report.component.ts2
-rw-r--r--client/src/app/videos/+video-edit/shared/video-caption-add-modal.component.ts2
-rw-r--r--client/src/app/videos/+video-watch/modal/video-share.component.ts2
-rw-r--r--client/src/app/videos/+video-watch/modal/video-support.component.ts2
-rw-r--r--client/src/sass/application.scss2
-rw-r--r--client/src/sass/bootstrap.scss8
26 files changed, 283 insertions, 53 deletions
diff --git a/client/src/app/+about/about-instance/contact-admin-modal.component.ts b/client/src/app/+about/about-instance/contact-admin-modal.component.ts
index 2ed41e741..d5e146b82 100644
--- a/client/src/app/+about/about-instance/contact-admin-modal.component.ts
+++ b/client/src/app/+about/about-instance/contact-admin-modal.component.ts
@@ -51,7 +51,7 @@ export class ContactAdminModalComponent extends FormReactive implements OnInit {
51 } 51 }
52 52
53 show () { 53 show () {
54 this.openedModal = this.modalService.open(this.modal, { keyboard: false }) 54 this.openedModal = this.modalService.open(this.modal, { centered: true, keyboard: false })
55 } 55 }
56 56
57 hide () { 57 hide () {
diff --git a/client/src/app/+accounts/accounts.component.html b/client/src/app/+accounts/accounts.component.html
index 915bee0a2..b982fba9a 100644
--- a/client/src/app/+accounts/accounts.component.html
+++ b/client/src/app/+accounts/accounts.component.html
@@ -38,12 +38,12 @@
38 </div> 38 </div>
39 </div> 39 </div>
40 40
41 <div class="links"> 41 <div class="links w-100">
42 <a i18n routerLink="video-channels" routerLinkActive="active" class="title-page">Video channels</a> 42 <ng-template #linkTemplate let-item="item">
43 <a [routerLink]="item.routerLink" routerLinkActive="active" class="title-page">{{ item.label }}</a>
44 </ng-template>
43 45
44 <a i18n routerLink="videos" routerLinkActive="active" class="title-page">Videos</a> 46 <list-overflow [items]="links" [itemTemplate]="linkTemplate"></list-overflow>
45
46 <a i18n routerLink="about" routerLinkActive="active" class="title-page">About</a>
47 </div> 47 </div>
48 </div> 48 </div>
49 49
diff --git a/client/src/app/+accounts/accounts.component.ts b/client/src/app/+accounts/accounts.component.ts
index a8157de0e..4fea0e4ed 100644
--- a/client/src/app/+accounts/accounts.component.ts
+++ b/client/src/app/+accounts/accounts.component.ts
@@ -10,6 +10,7 @@ import { User, UserRight } from '../../../../shared'
10import { I18n } from '@ngx-translate/i18n-polyfill' 10import { I18n } from '@ngx-translate/i18n-polyfill'
11import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' 11import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
12import { VideoChannel } from '@app/shared/video-channel/video-channel.model' 12import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
13import { ListOverflowItem } from '@app/shared/misc/list-overflow.component'
13 14
14@Component({ 15@Component({
15 templateUrl: './accounts.component.html', 16 templateUrl: './accounts.component.html',
@@ -19,6 +20,7 @@ export class AccountsComponent implements OnInit, OnDestroy {
19 account: Account 20 account: Account
20 accountUser: User 21 accountUser: User
21 videoChannels: VideoChannel[] = [] 22 videoChannels: VideoChannel[] = []
23 links: ListOverflowItem[] = []
22 24
23 isAccountManageable = false 25 isAccountManageable = false
24 accountFollowerTitle = '' 26 accountFollowerTitle = ''
@@ -70,6 +72,12 @@ export class AccountsComponent implements OnInit, OnDestroy {
70 72
71 err => this.notifier.error(err.message) 73 err => this.notifier.error(err.message)
72 ) 74 )
75
76 this.links = [
77 { label: this.i18n('Video channels'), routerLink: 'video-channels' },
78 { label: this.i18n('Videos'), routerLink: 'videos' },
79 { label: this.i18n('About'), routerLink: 'about' }
80 ]
73 } 81 }
74 82
75 ngOnDestroy () { 83 ngOnDestroy () {
diff --git a/client/src/app/+admin/admin.component.html b/client/src/app/+admin/admin.component.html
index 0d06aaedc..6c98fe453 100644
--- a/client/src/app/+admin/admin.component.html
+++ b/client/src/app/+admin/admin.component.html
@@ -1,28 +1,10 @@
1<div class="row"> 1<div class="row">
2 <div class="sub-menu"> 2 <div class="sub-menu">
3 <a i18n *ngIf="hasUsersRight()" routerLink="/admin/users" routerLinkActive="active" class="title-page"> 3 <ng-template #linkTemplate let-item="item">
4 Users 4 <a [routerLink]="item.routerLink" routerLinkActive="active" class="title-page">{{ item.label }}</a>
5 </a> 5 </ng-template>
6 6
7 <a i18n *ngIf="hasServerFollowRight()" routerLink="/admin/follows" routerLinkActive="active" class="title-page"> 7 <list-overflow [items]="items" [itemTemplate]="linkTemplate"></list-overflow>
8 Follows & redundancies
9 </a>
10
11 <a i18n *ngIf="hasVideoAbusesRight() || hasVideoBlacklistRight()" routerLink="/admin/moderation" routerLinkActive="active" class="title-page">
12 Moderation
13 </a>
14
15 <a i18n *ngIf="hasConfigRight()" routerLink="/admin/config" routerLinkActive="active" class="title-page">
16 Configuration
17 </a>
18
19 <a i18n *ngIf="hasPluginsRight()" routerLink="/admin/plugins" routerLinkActive="active" class="title-page">
20 Plugins/Themes
21 </a>
22
23 <a i18n *ngIf="hasJobsRight() || hasLogsRight() || hasDebugRight()" routerLink="/admin/system" routerLinkActive="active" class="title-page">
24 System
25 </a>
26 </div> 8 </div>
27 9
28 <div class="margin-content"> 10 <div class="margin-content">
diff --git a/client/src/app/+admin/admin.component.ts b/client/src/app/+admin/admin.component.ts
index b23999d40..9662522dc 100644
--- a/client/src/app/+admin/admin.component.ts
+++ b/client/src/app/+admin/admin.component.ts
@@ -1,12 +1,28 @@
1import { Component } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { UserRight } from '../../../../shared' 2import { UserRight } from '../../../../shared'
3import { AuthService } from '../core/auth/auth.service' 3import { AuthService } from '../core/auth/auth.service'
4import { ListOverflowItem } from '@app/shared/misc/list-overflow.component'
5import { I18n } from '@ngx-translate/i18n-polyfill'
4 6
5@Component({ 7@Component({
6 templateUrl: './admin.component.html' 8 templateUrl: './admin.component.html'
7}) 9})
8export class AdminComponent { 10export class AdminComponent implements OnInit {
9 constructor (private auth: AuthService) {} 11 items: ListOverflowItem[] = []
12
13 constructor (
14 private auth: AuthService,
15 private i18n: I18n
16 ) {}
17
18 ngOnInit () {
19 if (this.hasUsersRight()) this.items.push({ label: this.i18n('Users'), routerLink: '/admin/users' })
20 if (this.hasServerFollowRight()) this.items.push({ label: this.i18n('Follows & redundancies'), routerLink: '/admin/follows' })
21 if (this.hasVideoAbusesRight() || this.hasVideoBlacklistRight()) this.items.push({ label: this.i18n('Moderation'), routerLink: '/admin/moderation' })
22 if (this.hasConfigRight()) this.items.push({ label: this.i18n('Configuration'), routerLink: '/admin/config' })
23 if (this.hasPluginsRight()) this.items.push({ label: this.i18n('Plugins/Themes'), routerLink: '/admin/plugins' })
24 if (this.hasJobsRight() || this.hasLogsRight() || this.hasDebugRight()) this.items.push({ label: this.i18n('System'), routerLink: '/admin/system' })
25 }
10 26
11 hasUsersRight () { 27 hasUsersRight () {
12 return this.auth.getUser().hasRight(UserRight.MANAGE_USERS) 28 return this.auth.getUser().hasRight(UserRight.MANAGE_USERS)
diff --git a/client/src/app/+admin/moderation/video-abuse-list/moderation-comment-modal.component.ts b/client/src/app/+admin/moderation/video-abuse-list/moderation-comment-modal.component.ts
index f8a5ef8cb..29f90194b 100644
--- a/client/src/app/+admin/moderation/video-abuse-list/moderation-comment-modal.component.ts
+++ b/client/src/app/+admin/moderation/video-abuse-list/moderation-comment-modal.component.ts
@@ -38,7 +38,7 @@ export class ModerationCommentModalComponent extends FormReactive implements OnI
38 38
39 openModal (abuseToComment: VideoAbuse) { 39 openModal (abuseToComment: VideoAbuse) {
40 this.abuseToComment = abuseToComment 40 this.abuseToComment = abuseToComment
41 this.openedModal = this.modalService.open(this.modal) 41 this.openedModal = this.modalService.open(this.modal, { centered: true })
42 42
43 this.form.patchValue({ 43 this.form.patchValue({
44 moderationComment: this.abuseToComment.moderationComment 44 moderationComment: this.abuseToComment.moderationComment
diff --git a/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.ts b/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.ts
index 6df929ec9..d5682914e 100644
--- a/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.ts
+++ b/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.ts
@@ -53,7 +53,7 @@ export class MyAccountAcceptOwnershipComponent extends FormReactive implements O
53 show (videoChangeOwnership: VideoChangeOwnership) { 53 show (videoChangeOwnership: VideoChangeOwnership) {
54 this.videoChangeOwnership = videoChangeOwnership 54 this.videoChangeOwnership = videoChangeOwnership
55 this.modalService 55 this.modalService
56 .open(this.modal) 56 .open(this.modal, { centered: true })
57 .result 57 .result
58 .then(() => this.acceptOwnership()) 58 .then(() => this.acceptOwnership())
59 .catch(() => this.videoChangeOwnership = undefined) 59 .catch(() => this.videoChangeOwnership = undefined)
diff --git a/client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.ts b/client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.ts
index 36d1ea091..f4e2b5955 100644
--- a/client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.ts
+++ b/client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.ts
@@ -43,7 +43,7 @@ export class VideoChangeOwnershipComponent extends FormReactive implements OnIni
43 show (video: Video) { 43 show (video: Video) {
44 this.video = video 44 this.video = video
45 this.modalService 45 this.modalService
46 .open(this.modal) 46 .open(this.modal, { centered: true })
47 .result 47 .result
48 .then(() => this.changeOwnership()) 48 .then(() => this.changeOwnership())
49 .catch((_) => _) // Called when closing (cancel) the modal without validating, do nothing 49 .catch((_) => _) // Called when closing (cancel) the modal without validating, do nothing
diff --git a/client/src/app/+video-channels/video-channels.component.html b/client/src/app/+video-channels/video-channels.component.html
index debda9948..735a8f2c8 100644
--- a/client/src/app/+video-channels/video-channels.component.html
+++ b/client/src/app/+video-channels/video-channels.component.html
@@ -29,10 +29,12 @@
29 </div> 29 </div>
30 </div> 30 </div>
31 31
32 <div class="links"> 32 <div class="links w-100">
33 <a i18n routerLink="videos" routerLinkActive="active" class="title-page">Videos</a> 33 <ng-template #linkTemplate let-item="item">
34 <a i18n routerLink="video-playlists" routerLinkActive="active" class="title-page">Video playlists</a> 34 <a [routerLink]="item.routerLink" routerLinkActive="active" class="title-page">{{ item.label }}</a>
35 <a i18n routerLink="about" routerLinkActive="active" class="title-page">About</a> 35 </ng-template>
36
37 <list-overflow [items]="links" [itemTemplate]="linkTemplate"></list-overflow>
36 </div> 38 </div>
37 </div> 39 </div>
38 40
diff --git a/client/src/app/+video-channels/video-channels.component.ts b/client/src/app/+video-channels/video-channels.component.ts
index 5ca9581a8..0889ca854 100644
--- a/client/src/app/+video-channels/video-channels.component.ts
+++ b/client/src/app/+video-channels/video-channels.component.ts
@@ -9,6 +9,7 @@ import { AuthService, Notifier } from '@app/core'
9import { Hotkey, HotkeysService } from 'angular2-hotkeys' 9import { Hotkey, HotkeysService } from 'angular2-hotkeys'
10import { SubscribeButtonComponent } from '@app/shared/user-subscription/subscribe-button.component' 10import { SubscribeButtonComponent } from '@app/shared/user-subscription/subscribe-button.component'
11import { I18n } from '@ngx-translate/i18n-polyfill' 11import { I18n } from '@ngx-translate/i18n-polyfill'
12import { ListOverflowItem } from '@app/shared/misc/list-overflow.component'
12 13
13@Component({ 14@Component({
14 templateUrl: './video-channels.component.html', 15 templateUrl: './video-channels.component.html',
@@ -19,6 +20,7 @@ export class VideoChannelsComponent implements OnInit, OnDestroy {
19 20
20 videoChannel: VideoChannel 21 videoChannel: VideoChannel
21 hotkeys: Hotkey[] 22 hotkeys: Hotkey[]
23 links: ListOverflowItem[] = []
22 isChannelManageable = false 24 isChannelManageable = false
23 25
24 private routeSub: Subscription 26 private routeSub: Subscription
@@ -62,6 +64,12 @@ export class VideoChannelsComponent implements OnInit, OnDestroy {
62 }, undefined, this.i18n('Subscribe to the account')) 64 }, undefined, this.i18n('Subscribe to the account'))
63 ] 65 ]
64 if (this.isUserLoggedIn()) this.hotkeysService.add(this.hotkeys) 66 if (this.isUserLoggedIn()) this.hotkeysService.add(this.hotkeys)
67
68 this.links = [
69 { label: this.i18n('Videos'), routerLink: 'videos' },
70 { label: this.i18n('Video playlists'), routerLink: 'video-playlists' },
71 { label: this.i18n('About'), routerLink: 'about' }
72 ]
65 } 73 }
66 74
67 ngOnDestroy () { 75 ngOnDestroy () {
diff --git a/client/src/app/menu/language-chooser.component.ts b/client/src/app/menu/language-chooser.component.ts
index 4a6e4c75a..43f622dfb 100644
--- a/client/src/app/menu/language-chooser.component.ts
+++ b/client/src/app/menu/language-chooser.component.ts
@@ -21,7 +21,7 @@ export class LanguageChooserComponent {
21 } 21 }
22 22
23 show () { 23 show () {
24 this.modalService.open(this.modal) 24 this.modalService.open(this.modal, { centered: true })
25 } 25 }
26 26
27 buildLanguageLink (lang: { id: string }) { 27 buildLanguageLink (lang: { id: string }) {
diff --git a/client/src/app/modal/instance-config-warning-modal.component.ts b/client/src/app/modal/instance-config-warning-modal.component.ts
index 742a7dd41..5e1433548 100644
--- a/client/src/app/modal/instance-config-warning-modal.component.ts
+++ b/client/src/app/modal/instance-config-warning-modal.component.ts
@@ -24,7 +24,7 @@ export class InstanceConfigWarningModalComponent {
24 show (about: About) { 24 show (about: About) {
25 this.about = about 25 this.about = about
26 26
27 const ref = this.modalService.open(this.modal) 27 const ref = this.modalService.open(this.modal, { centered: true })
28 28
29 ref.result.finally(() => { 29 ref.result.finally(() => {
30 if (this.stopDisplayModal === true) this.doNotOpenAgain() 30 if (this.stopDisplayModal === true) this.doNotOpenAgain()
diff --git a/client/src/app/modal/welcome-modal.component.ts b/client/src/app/modal/welcome-modal.component.ts
index 19a147b85..e022776e3 100644
--- a/client/src/app/modal/welcome-modal.component.ts
+++ b/client/src/app/modal/welcome-modal.component.ts
@@ -18,7 +18,8 @@ export class WelcomeModalComponent {
18 ) { } 18 ) { }
19 19
20 show () { 20 show () {
21 this.modalService.open(this.modal,{ 21 this.modalService.open(this.modal, {
22 centered: true,
22 backdrop: 'static', 23 backdrop: 'static',
23 keyboard: false, 24 keyboard: false,
24 size: 'lg' 25 size: 'lg'
diff --git a/client/src/app/shared/misc/list-overflow.component.html b/client/src/app/shared/misc/list-overflow.component.html
new file mode 100644
index 000000000..986572801
--- /dev/null
+++ b/client/src/app/shared/misc/list-overflow.component.html
@@ -0,0 +1,35 @@
1<div #itemsParent class="d-flex align-items-center text-nowrap w-100 list-overflow-parent">
2 <span [id]="getId(id)" #itemsRendered *ngFor="let item of items; index as id">
3 <ng-container *ngTemplateOutlet="itemTemplate; context: {item: item}"></ng-container>
4 </span>
5
6 <ng-container *ngIf="isMenuDisplayed()">
7 <button *ngIf="isInMobileView" class="btn btn-outline-secondary btn-sm list-overflow-menu" (click)="toggleModal()">
8 <span class="glyphicon glyphicon-chevron-down"></span>
9 </button>
10
11 <div *ngIf="!isInMobileView" class="list-overflow-menu" ngbDropdown container="body" #dropdown="ngbDropdown" (mouseleave)="closeDropdownIfHovered(dropdown)" (mouseenter)="openDropdownOnHover(dropdown)">
12 <button class="btn btn-outline-secondary btn-sm" [ngClass]="{ routeActive: active }"
13 ngbDropdownAnchor (click)="dropdownAnchorClicked(dropdown)" role="button"
14 >
15 <span class="glyphicon glyphicon-chevron-down"></span>
16 </button>
17
18 <div ngbDropdownMenu>
19 <a *ngFor="let item of items | slice:showItemsUntilIndexExcluded:items.length"
20 [routerLink]="item.routerLink" routerLinkActive="active" class="dropdown-item">
21 {{ item.label }}
22 </a>
23 </div>
24 </div>
25 </ng-container>
26</div >
27
28<ng-template #modal let-close="close" let-dismiss="dismiss">
29 <div class="modal-body">
30 <a *ngFor="let item of items | slice:showItemsUntilIndexExcluded:items.length"
31 [routerLink]="item.routerLink" routerLinkActive="active" (click)="dismissOtherModals()">
32 {{ item.label }}
33 </a>
34 </div>
35</ng-template>
diff --git a/client/src/app/shared/misc/list-overflow.component.scss b/client/src/app/shared/misc/list-overflow.component.scss
new file mode 100644
index 000000000..e26100aca
--- /dev/null
+++ b/client/src/app/shared/misc/list-overflow.component.scss
@@ -0,0 +1,61 @@
1@import '_mixins';
2
3:host {
4 width: 100%;
5}
6
7.list-overflow-parent {
8 overflow: hidden;
9}
10
11.list-overflow-menu {
12 position: absolute;
13 right: 0;
14}
15
16button {
17 width: 30px;
18 border: none;
19
20 &::after {
21 display: none;
22 }
23
24 &.routeActive {
25 &::after {
26 display: inherit;
27 border: 2px solid var(--mainColor);
28 position: relative;
29 right: 95%;
30 top: 50%;
31 }
32 }
33}
34
35::ng-deep .dropdown-menu {
36 margin-top: 0 !important;
37 position: static;
38 right: auto;
39 bottom: auto
40}
41
42.modal-body {
43 a {
44 @include disable-default-a-behaviour;
45
46 color: currentColor;
47 box-sizing: border-box;
48 display: block;
49 font-size: 1.2rem;
50 padding: 9px 12px;
51 text-align: initial;
52 text-transform: unset;
53 width: 100%;
54
55 &.active {
56 color: var(--mainBackgroundColor) !important;
57 background-color: var(--mainHoverColor);
58 opacity: .9;
59 }
60 }
61}
diff --git a/client/src/app/shared/misc/list-overflow.component.ts b/client/src/app/shared/misc/list-overflow.component.ts
new file mode 100644
index 000000000..4f92c0f7c
--- /dev/null
+++ b/client/src/app/shared/misc/list-overflow.component.ts
@@ -0,0 +1,114 @@
1import {
2 Component,
3 Input,
4 TemplateRef,
5 ViewChildren,
6 ViewChild,
7 QueryList,
8 ChangeDetectionStrategy,
9 ElementRef,
10 ChangeDetectorRef,
11 HostListener
12} from '@angular/core'
13import { NgbModal, NgbDropdown } from '@ng-bootstrap/ng-bootstrap'
14import { uniqueId, lowerFirst } from 'lodash-es'
15import { ScreenService } from './screen.service'
16import { take } from 'rxjs/operators'
17
18export interface ListOverflowItem {
19 label: string
20 routerLink: string | any[]
21}
22
23@Component({
24 selector: 'list-overflow',
25 templateUrl: './list-overflow.component.html',
26 styleUrls: [ './list-overflow.component.scss' ],
27 changeDetection: ChangeDetectionStrategy.OnPush
28})
29export class ListOverflowComponent<T extends ListOverflowItem> {
30 @ViewChild('modal', { static: true }) modal: ElementRef
31 @ViewChild('itemsParent', { static: true }) parent: ElementRef<HTMLDivElement>
32 @ViewChildren('itemsRendered') itemsRendered: QueryList<ElementRef>
33 @Input() items: T[]
34 @Input() itemTemplate: TemplateRef<{item: T}>
35
36 showItemsUntilIndexExcluded: number
37 active = false
38 isInTouchScreen = false
39 isInMobileView = false
40
41 private openedOnHover = false
42
43 constructor (
44 private cdr: ChangeDetectorRef,
45 private modalService: NgbModal,
46 private screenService: ScreenService
47 ) {}
48
49 isMenuDisplayed () {
50 return !!this.showItemsUntilIndexExcluded
51 }
52
53 @HostListener('window:resize', ['$event'])
54 onWindowResize () {
55 this.isInTouchScreen = !!this.screenService.isInTouchScreen()
56 this.isInMobileView = !!this.screenService.isInMobileView()
57
58 const parentWidth = this.parent.nativeElement.getBoundingClientRect().width
59 let showItemsUntilIndexExcluded: number
60 let accWidth = 0
61
62 for (const [index, el] of this.itemsRendered.toArray().entries()) {
63 accWidth += el.nativeElement.getBoundingClientRect().width
64 if (showItemsUntilIndexExcluded === undefined) {
65 showItemsUntilIndexExcluded = (parentWidth < accWidth) ? index : undefined
66 }
67
68 const e = document.getElementById(this.getId(index))
69 const shouldBeVisible = showItemsUntilIndexExcluded ? index < showItemsUntilIndexExcluded : true
70 e.style.visibility = shouldBeVisible ? 'inherit' : 'hidden'
71 }
72
73 this.showItemsUntilIndexExcluded = showItemsUntilIndexExcluded
74 this.cdr.markForCheck()
75 }
76
77 openDropdownOnHover (dropdown: NgbDropdown) {
78 this.openedOnHover = true
79 dropdown.open()
80
81 // Menu was closed
82 dropdown.openChange
83 .pipe(take(1))
84 .subscribe(() => this.openedOnHover = false)
85 }
86
87 dropdownAnchorClicked (dropdown: NgbDropdown) {
88 if (this.openedOnHover) {
89 this.openedOnHover = false
90 return
91 }
92
93 return dropdown.toggle()
94 }
95
96 closeDropdownIfHovered (dropdown: NgbDropdown) {
97 if (this.openedOnHover === false) return
98
99 dropdown.close()
100 this.openedOnHover = false
101 }
102
103 toggleModal () {
104 this.modalService.open(this.modal, { centered: true })
105 }
106
107 dismissOtherModals () {
108 this.modalService.dismissAll()
109 }
110
111 getId (id: number | string = uniqueId()): string {
112 return lowerFirst(this.constructor.name) + '_' + id
113 }
114}
diff --git a/client/src/app/shared/moderation/user-ban-modal.component.ts b/client/src/app/shared/moderation/user-ban-modal.component.ts
index cf0e1577a..1647e3691 100644
--- a/client/src/app/shared/moderation/user-ban-modal.component.ts
+++ b/client/src/app/shared/moderation/user-ban-modal.component.ts
@@ -39,7 +39,7 @@ export class UserBanModalComponent extends FormReactive implements OnInit {
39 39
40 openModal (user: User | User[]) { 40 openModal (user: User | User[]) {
41 this.usersToBan = user 41 this.usersToBan = user
42 this.openedModal = this.modalService.open(this.modal) 42 this.openedModal = this.modalService.open(this.modal, { centered: true })
43 } 43 }
44 44
45 hide () { 45 hide () {
diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts
index 759de7020..98211c727 100644
--- a/client/src/app/shared/shared.module.ts
+++ b/client/src/app/shared/shared.module.ts
@@ -5,6 +5,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms'
5import { RouterModule } from '@angular/router' 5import { RouterModule } from '@angular/router'
6import { MarkdownTextareaComponent } from '@app/shared/forms/markdown-textarea.component' 6import { MarkdownTextareaComponent } from '@app/shared/forms/markdown-textarea.component'
7import { HelpComponent } from '@app/shared/misc/help.component' 7import { HelpComponent } from '@app/shared/misc/help.component'
8import { ListOverflowComponent } from '@app/shared/misc/list-overflow.component'
8import { InfiniteScrollerDirective } from '@app/shared/video/infinite-scroller.directive' 9import { InfiniteScrollerDirective } from '@app/shared/video/infinite-scroller.directive'
9import { BytesPipe, KeysPipe, NgPipesModule } from 'ngx-pipes' 10import { BytesPipe, KeysPipe, NgPipesModule } from 'ngx-pipes'
10import { SharedModule as PrimeSharedModule } from 'primeng/api' 11import { SharedModule as PrimeSharedModule } from 'primeng/api'
@@ -156,6 +157,7 @@ import { ClipboardModule } from '@angular/cdk/clipboard'
156 InfiniteScrollerDirective, 157 InfiniteScrollerDirective,
157 TextareaAutoResizeDirective, 158 TextareaAutoResizeDirective,
158 HelpComponent, 159 HelpComponent,
160 ListOverflowComponent,
159 161
160 ReactiveFileComponent, 162 ReactiveFileComponent,
161 PeertubeCheckboxComponent, 163 PeertubeCheckboxComponent,
@@ -227,6 +229,7 @@ import { ClipboardModule } from '@angular/cdk/clipboard'
227 InfiniteScrollerDirective, 229 InfiniteScrollerDirective,
228 TextareaAutoResizeDirective, 230 TextareaAutoResizeDirective,
229 HelpComponent, 231 HelpComponent,
232 ListOverflowComponent,
230 InputReadonlyCopyComponent, 233 InputReadonlyCopyComponent,
231 234
232 ReactiveFileComponent, 235 ReactiveFileComponent,
diff --git a/client/src/app/shared/video/modals/video-blacklist.component.ts b/client/src/app/shared/video/modals/video-blacklist.component.ts
index bdd9c7b99..6ef9c250b 100644
--- a/client/src/app/shared/video/modals/video-blacklist.component.ts
+++ b/client/src/app/shared/video/modals/video-blacklist.component.ts
@@ -46,7 +46,7 @@ export class VideoBlacklistComponent extends FormReactive implements OnInit {
46 } 46 }
47 47
48 show () { 48 show () {
49 this.openedModal = this.modalService.open(this.modal, { keyboard: false }) 49 this.openedModal = this.modalService.open(this.modal, { centered: true, keyboard: false })
50 } 50 }
51 51
52 hide () { 52 hide () {
diff --git a/client/src/app/shared/video/modals/video-download.component.ts b/client/src/app/shared/video/modals/video-download.component.ts
index c1ceca263..6909c4279 100644
--- a/client/src/app/shared/video/modals/video-download.component.ts
+++ b/client/src/app/shared/video/modals/video-download.component.ts
@@ -48,7 +48,7 @@ export class VideoDownloadComponent {
48 this.video = video 48 this.video = video
49 this.videoCaptions = videoCaptions && videoCaptions.length ? videoCaptions : undefined 49 this.videoCaptions = videoCaptions && videoCaptions.length ? videoCaptions : undefined
50 50
51 this.activeModal = this.modalService.open(this.modal) 51 this.activeModal = this.modalService.open(this.modal, { centered: true })
52 52
53 this.resolutionId = this.getVideoFiles()[0].resolution.id 53 this.resolutionId = this.getVideoFiles()[0].resolution.id
54 if (this.videoCaptions) this.subtitleLanguageId = this.videoCaptions[0].language.id 54 if (this.videoCaptions) this.subtitleLanguageId = this.videoCaptions[0].language.id
diff --git a/client/src/app/shared/video/modals/video-report.component.ts b/client/src/app/shared/video/modals/video-report.component.ts
index ee991fade..988fa03d4 100644
--- a/client/src/app/shared/video/modals/video-report.component.ts
+++ b/client/src/app/shared/video/modals/video-report.component.ts
@@ -53,7 +53,7 @@ export class VideoReportComponent extends FormReactive implements OnInit {
53 } 53 }
54 54
55 show () { 55 show () {
56 this.openedModal = this.modalService.open(this.modal, { keyboard: false }) 56 this.openedModal = this.modalService.open(this.modal, { centered: true, keyboard: false })
57 } 57 }
58 58
59 hide () { 59 hide () {
diff --git a/client/src/app/videos/+video-edit/shared/video-caption-add-modal.component.ts b/client/src/app/videos/+video-edit/shared/video-caption-add-modal.component.ts
index 1a9bf5171..9856aac9e 100644
--- a/client/src/app/videos/+video-edit/shared/video-caption-add-modal.component.ts
+++ b/client/src/app/videos/+video-edit/shared/video-caption-add-modal.component.ts
@@ -56,7 +56,7 @@ export class VideoCaptionAddModalComponent extends FormReactive implements OnIni
56 show () { 56 show () {
57 this.closingModal = false 57 this.closingModal = false
58 58
59 this.openedModal = this.modalService.open(this.modal, { keyboard: false }) 59 this.openedModal = this.modalService.open(this.modal, { centered: true, keyboard: false })
60 } 60 }
61 61
62 hide () { 62 hide () {
diff --git a/client/src/app/videos/+video-watch/modal/video-share.component.ts b/client/src/app/videos/+video-watch/modal/video-share.component.ts
index 6bc9b09fa..5109bcd11 100644
--- a/client/src/app/videos/+video-watch/modal/video-share.component.ts
+++ b/client/src/app/videos/+video-watch/modal/video-share.component.ts
@@ -72,7 +72,7 @@ export class VideoShareComponent {
72 controls: true 72 controls: true
73 } 73 }
74 74
75 this.modalService.open(this.modal) 75 this.modalService.open(this.modal, { centered: true })
76 } 76 }
77 77
78 getVideoIframeCode () { 78 getVideoIframeCode () {
diff --git a/client/src/app/videos/+video-watch/modal/video-support.component.ts b/client/src/app/videos/+video-watch/modal/video-support.component.ts
index b56a51fbf..0058172f2 100644
--- a/client/src/app/videos/+video-watch/modal/video-support.component.ts
+++ b/client/src/app/videos/+video-watch/modal/video-support.component.ts
@@ -21,7 +21,7 @@ export class VideoSupportComponent {
21 ) { } 21 ) { }
22 22
23 show () { 23 show () {
24 this.modalService.open(this.modal) 24 this.modalService.open(this.modal, { centered: true })
25 25
26 this.markdownService.enhancedMarkdownToHTML(this.video.support) 26 this.markdownService.enhancedMarkdownToHTML(this.video.support)
27 .then(r => this.videoHTMLSupport = r) 27 .then(r => this.videoHTMLSupport = r)
diff --git a/client/src/sass/application.scss b/client/src/sass/application.scss
index 995cc6025..e4840dd81 100644
--- a/client/src/sass/application.scss
+++ b/client/src/sass/application.scss
@@ -252,7 +252,7 @@ table {
252 padding-left: 50px; 252 padding-left: 50px;
253 253
254 .title-page { 254 .title-page {
255 font-size: 15px; 255 font-size: 17px;
256 } 256 }
257 } 257 }
258 } 258 }
diff --git a/client/src/sass/bootstrap.scss b/client/src/sass/bootstrap.scss
index 2aca8c380..035270e89 100644
--- a/client/src/sass/bootstrap.scss
+++ b/client/src/sass/bootstrap.scss
@@ -30,8 +30,10 @@ $icon-font-path: '~@neos21/bootstrap3-glyphicons/assets/fonts/';
30 .dropdown-item { 30 .dropdown-item {
31 padding: 3px 15px; 31 padding: 3px 15px;
32 32
33 &:active { 33 &.active {
34 color: #000 !important; 34 color: var(--mainBackgroundColor) !important;
35 background-color: var(--mainHoverColor);
36 opacity: .9;
35 } 37 }
36 } 38 }
37 39
@@ -48,14 +50,12 @@ $icon-font-path: '~@neos21/bootstrap3-glyphicons/assets/fonts/';
48 50
49@media screen and (min-width: 768px) { 51@media screen and (min-width: 768px) {
50 .modal:before { 52 .modal:before {
51 display: inline-block;
52 vertical-align: middle; 53 vertical-align: middle;
53 content: " "; 54 content: " ";
54 height: 100%; 55 height: 100%;
55 } 56 }
56 57
57 .modal-dialog { 58 .modal-dialog {
58 display: inline-block;
59 text-align: left; 59 text-align: left;
60 vertical-align: middle; 60 vertical-align: middle;
61 min-width: 500px; 61 min-width: 500px;