1 import { fromEvent } from 'rxjs'
2 import { debounceTime } from 'rxjs/operators'
3 import { Injectable } from '@angular/core'
4 import { GlobalIconName } from '@app/shared/shared-icons'
5 import { HTMLServerConfig } from '@shared/models/server'
6 import { ScreenService } from '../wrappers'
8 export type MenuLink = {
12 // Used by the left menu for example
18 export type MenuSection = {
25 export class MenuService {
26 isMenuDisplayed = true
27 isMenuChangedByUser = false
28 menuWidth = 240 // should be kept equal to $menu-width
31 private screenService: ScreenService
33 // Do not display menu on small or touch screens
34 if (this.screenService.isInSmallView() || this.screenService.isInTouchScreen()) {
35 this.setMenuDisplay(false)
38 this.handleWindowResize()
42 this.setMenuDisplay(!this.isMenuDisplayed)
43 this.isMenuChangedByUser = true
47 return this.isMenuDisplayed
50 setMenuDisplay (display: boolean) {
51 this.isMenuDisplayed = display
53 if (!this.screenService.isInTouchScreen()) return
55 // On touch screens, lock body scroll and display content overlay when memu is opened
56 if (this.isMenuDisplayed) {
57 document.body.classList.add('menu-open')
58 this.screenService.onFingerSwipe('left', () => this.setMenuDisplay(false))
62 document.body.classList.remove('menu-open')
66 this.isMenuDisplayed = window.innerWidth >= 800 && !this.isMenuChangedByUser
69 buildLibraryLinks (userCanSeeVideosLink: boolean): MenuSection {
70 let links: MenuLink[] = []
72 if (userCanSeeVideosLink) {
74 path: '/my-library/videos',
75 icon: 'videos' as GlobalIconName,
76 shortLabel: $localize`Videos`,
77 label: $localize`My videos`
81 links = links.concat([
83 path: '/my-library/video-playlists',
84 icon: 'playlists' as GlobalIconName,
85 shortLabel: $localize`Playlists`,
86 label: $localize`My playlists`
89 path: '/videos/subscriptions',
90 icon: 'subscriptions' as GlobalIconName,
91 shortLabel: $localize`Subscriptions`,
92 label: $localize`My subscriptions`
95 path: '/my-library/history/videos',
96 icon: 'history' as GlobalIconName,
97 shortLabel: $localize`History`,
98 label: $localize`My history`
103 key: 'in-my-library',
104 title: $localize`In my library`,
109 buildCommonLinks (config: HTMLServerConfig): MenuSection {
110 let links: MenuLink[] = []
112 if (config.homepage.enabled) {
114 icon: 'home' as 'home',
115 label: $localize`Home`,
116 shortLabel: $localize`Home`,
121 links = links.concat([
123 icon: 'globe' as 'globe',
124 label: $localize`Discover videos`,
125 shortLabel: $localize`Discover`,
126 path: '/videos/overview'
129 icon: 'trending' as 'trending',
130 label: $localize`Trending videos`,
131 shortLabel: $localize`Trending`,
132 path: '/videos/trending'
135 icon: 'recently-added' as 'recently-added',
136 label: $localize`Recently added videos`,
137 shortLabel: $localize`Recently added`,
138 path: '/videos/recently-added'
141 icon: 'local' as 'local',
142 label: $localize`Local videos`,
143 shortLabel: $localize`Local videos`,
144 path: '/videos/local'
150 title: $localize`ON ${config.instance.name}`,
155 private handleWindowResize () {
156 // On touch screens, do not handle window resize event since opened menu is handled with a content overlay
157 if (this.screenService.isInTouchScreen()) return
159 fromEvent(window, 'resize')
160 .pipe(debounceTime(200))
161 .subscribe(() => this.onResize())