mirror of https://github.com/Chocobozzz/PeerTube
118 lines
3.0 KiB
TypeScript
118 lines
3.0 KiB
TypeScript
import { fromEvent } from 'rxjs'
|
|
import { debounceTime } from 'rxjs/operators'
|
|
import { Injectable } from '@angular/core'
|
|
import { GlobalIconName } from '@app/shared/shared-icons'
|
|
import { sortObjectComparator } from '@shared/core-utils/miscs/miscs'
|
|
import { ServerConfig } from '@shared/models/server'
|
|
import { ScreenService } from '../wrappers'
|
|
|
|
export type MenuLink = {
|
|
icon: GlobalIconName
|
|
label: string
|
|
menuLabel: string
|
|
path: string
|
|
priority: number
|
|
}
|
|
|
|
@Injectable()
|
|
export class MenuService {
|
|
isMenuDisplayed = true
|
|
isMenuChangedByUser = false
|
|
menuWidth = 240 // should be kept equal to $menu-width
|
|
|
|
constructor (
|
|
private screenService: ScreenService
|
|
) {
|
|
// Do not display menu on small or touch screens
|
|
if (this.screenService.isInSmallView() || this.screenService.isInTouchScreen()) {
|
|
this.setMenuDisplay(false)
|
|
}
|
|
|
|
this.handleWindowResize()
|
|
}
|
|
|
|
toggleMenu () {
|
|
this.setMenuDisplay(!this.isMenuDisplayed)
|
|
this.isMenuChangedByUser = true
|
|
}
|
|
|
|
isDisplayed () {
|
|
return this.isMenuDisplayed
|
|
}
|
|
|
|
setMenuDisplay (display: boolean) {
|
|
this.isMenuDisplayed = display
|
|
|
|
if (!this.screenService.isInTouchScreen()) return
|
|
|
|
// On touch screens, lock body scroll and display content overlay when memu is opened
|
|
if (this.isMenuDisplayed) {
|
|
document.body.classList.add('menu-open')
|
|
this.screenService.onFingerSwipe('left', () => { this.setMenuDisplay(false) })
|
|
return
|
|
}
|
|
|
|
document.body.classList.remove('menu-open')
|
|
}
|
|
|
|
onResize () {
|
|
this.isMenuDisplayed = window.innerWidth >= 800 && !this.isMenuChangedByUser
|
|
}
|
|
|
|
buildCommonLinks (config: ServerConfig) {
|
|
let entries: MenuLink[] = [
|
|
{
|
|
icon: 'globe' as 'globe',
|
|
label: $localize`Discover videos`,
|
|
menuLabel: $localize`Discover`,
|
|
path: '/videos/overview',
|
|
priority: 150
|
|
},
|
|
{
|
|
icon: 'trending' as 'trending',
|
|
label: $localize`Trending videos`,
|
|
menuLabel: $localize`Trending`,
|
|
path: '/videos/trending',
|
|
priority: 140
|
|
},
|
|
{
|
|
icon: 'recently-added' as 'recently-added',
|
|
label: $localize`Recently added videos`,
|
|
menuLabel: $localize`Recently added`,
|
|
path: '/videos/recently-added',
|
|
priority: 130
|
|
},
|
|
{
|
|
icon: 'local' as 'local',
|
|
label: $localize`Local videos`,
|
|
menuLabel: $localize`Local videos`,
|
|
path: '/videos/local',
|
|
priority: 120
|
|
}
|
|
]
|
|
|
|
if (config.homepage.enabled) {
|
|
entries.push({
|
|
icon: 'home' as 'home',
|
|
label: $localize`Home`,
|
|
menuLabel: $localize`Home`,
|
|
path: '/home',
|
|
priority: 160
|
|
})
|
|
}
|
|
|
|
entries = entries.sort(sortObjectComparator('priority', 'desc'))
|
|
|
|
return entries
|
|
}
|
|
|
|
private handleWindowResize () {
|
|
// On touch screens, do not handle window resize event since opened menu is handled with a content overlay
|
|
if (this.screenService.isInTouchScreen()) return
|
|
|
|
fromEvent(window, 'resize')
|
|
.pipe(debounceTime(200))
|
|
.subscribe(() => this.onResize())
|
|
}
|
|
}
|