]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/shared/shared-main/misc/list-overflow.component.ts
Migrate client to eslint
[github/Chocobozzz/PeerTube.git] / client / src / app / shared / shared-main / misc / list-overflow.component.ts
1 import { lowerFirst, uniqueId } from 'lodash-es'
2 import { take } from 'rxjs/operators'
3 import {
4 AfterViewInit,
5 ChangeDetectionStrategy,
6 ChangeDetectorRef,
7 Component,
8 ElementRef,
9 HostListener,
10 Input,
11 QueryList,
12 TemplateRef,
13 ViewChild,
14 ViewChildren
15 } from '@angular/core'
16 import { ScreenService } from '@app/core'
17 import { NgbDropdown, NgbModal } from '@ng-bootstrap/ng-bootstrap'
18
19 export interface ListOverflowItem {
20 label: string
21 routerLink: string | any[]
22 }
23
24 @Component({
25 selector: 'my-list-overflow',
26 templateUrl: './list-overflow.component.html',
27 styleUrls: [ './list-overflow.component.scss' ],
28 changeDetection: ChangeDetectionStrategy.OnPush
29 })
30 export class ListOverflowComponent<T extends ListOverflowItem> implements AfterViewInit {
31 @Input() items: T[]
32 @Input() itemTemplate: TemplateRef<{item: T}>
33
34 @ViewChild('modal', { static: true }) modal: ElementRef
35 @ViewChild('itemsParent', { static: true }) parent: ElementRef<HTMLDivElement>
36 @ViewChildren('itemsRendered') itemsRendered: QueryList<ElementRef>
37
38 showItemsUntilIndexExcluded: number
39 active = false
40 isInTouchScreen = false
41 isInMobileView = false
42
43 private openedOnHover = false
44
45 constructor (
46 private cdr: ChangeDetectorRef,
47 private modalService: NgbModal,
48 private screenService: ScreenService
49 ) {}
50
51 ngAfterViewInit () {
52 setTimeout(() => this.onWindowResize(), 0)
53 }
54
55 isMenuDisplayed () {
56 return !!this.showItemsUntilIndexExcluded
57 }
58
59 @HostListener('window:resize')
60 onWindowResize () {
61 this.isInTouchScreen = !!this.screenService.isInTouchScreen()
62 this.isInMobileView = !!this.screenService.isInMobileView()
63
64 const parentWidth = this.parent.nativeElement.getBoundingClientRect().width
65 let showItemsUntilIndexExcluded: number
66 let accWidth = 0
67
68 for (const [ index, el ] of this.itemsRendered.toArray().entries()) {
69 accWidth += el.nativeElement.getBoundingClientRect().width
70 if (showItemsUntilIndexExcluded === undefined) {
71 showItemsUntilIndexExcluded = (parentWidth < accWidth) ? index : undefined
72 }
73
74 const e = document.getElementById(this.getId(index))
75 const shouldBeVisible = showItemsUntilIndexExcluded ? index < showItemsUntilIndexExcluded : true
76 e.style.visibility = shouldBeVisible ? 'inherit' : 'hidden'
77 }
78
79 this.showItemsUntilIndexExcluded = showItemsUntilIndexExcluded
80 this.cdr.markForCheck()
81 }
82
83 openDropdownOnHover (dropdown: NgbDropdown) {
84 this.openedOnHover = true
85 dropdown.open()
86
87 // Menu was closed
88 dropdown.openChange
89 .pipe(take(1))
90 .subscribe(() => this.openedOnHover = false)
91 }
92
93 dropdownAnchorClicked (dropdown: NgbDropdown) {
94 if (this.openedOnHover) {
95 this.openedOnHover = false
96 return
97 }
98
99 return dropdown.toggle()
100 }
101
102 closeDropdownIfHovered (dropdown: NgbDropdown) {
103 if (this.openedOnHover === false) return
104
105 dropdown.close()
106 this.openedOnHover = false
107 }
108
109 toggleModal () {
110 this.modalService.open(this.modal, { centered: true })
111 }
112
113 dismissOtherModals () {
114 this.modalService.dismissAll()
115 }
116
117 getId (id: number | string = uniqueId()): string {
118 return lowerFirst(this.constructor.name) + '_' + id
119 }
120 }