]>
Commit | Line | Data |
---|---|---|
1 | import { Hotkey, HotkeysService } from 'angular2-hotkeys' | |
2 | import { Subscription } from 'rxjs' | |
3 | import { catchError, distinctUntilChanged, map, switchMap } from 'rxjs/operators' | |
4 | import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core' | |
5 | import { ActivatedRoute } from '@angular/router' | |
6 | import { AuthService, MarkdownService, Notifier, RestExtractor, ScreenService } from '@app/core' | |
7 | import { Account, ListOverflowItem, VideoChannel, VideoChannelService, VideoService } from '@app/shared/shared-main' | |
8 | import { BlocklistService } from '@app/shared/shared-moderation' | |
9 | import { SupportModalComponent } from '@app/shared/shared-support-modal' | |
10 | import { SubscribeButtonComponent } from '@app/shared/shared-user-subscription' | |
11 | import { HttpStatusCode, UserRight } from '@shared/models' | |
12 | ||
13 | @Component({ | |
14 | templateUrl: './video-channels.component.html', | |
15 | styleUrls: [ './video-channels.component.scss' ] | |
16 | }) | |
17 | export class VideoChannelsComponent implements OnInit, OnDestroy { | |
18 | @ViewChild('subscribeButton') subscribeButton: SubscribeButtonComponent | |
19 | @ViewChild('supportModal') supportModal: SupportModalComponent | |
20 | ||
21 | videoChannel: VideoChannel | |
22 | ownerAccount: Account | |
23 | hotkeys: Hotkey[] | |
24 | links: ListOverflowItem[] = [] | |
25 | isChannelManageable = false | |
26 | ||
27 | channelVideosCount: number | |
28 | ownerDescriptionHTML = '' | |
29 | channelDescriptionHTML = '' | |
30 | channelDescriptionExpanded = false | |
31 | ||
32 | private routeSub: Subscription | |
33 | ||
34 | constructor ( | |
35 | private route: ActivatedRoute, | |
36 | private notifier: Notifier, | |
37 | private authService: AuthService, | |
38 | private videoChannelService: VideoChannelService, | |
39 | private videoService: VideoService, | |
40 | private restExtractor: RestExtractor, | |
41 | private hotkeysService: HotkeysService, | |
42 | private screenService: ScreenService, | |
43 | private markdown: MarkdownService, | |
44 | private blocklist: BlocklistService | |
45 | ) { } | |
46 | ||
47 | ngOnInit () { | |
48 | this.routeSub = this.route.params | |
49 | .pipe( | |
50 | map(params => params['videoChannelName']), | |
51 | distinctUntilChanged(), | |
52 | switchMap(videoChannelName => this.videoChannelService.getVideoChannel(videoChannelName)), | |
53 | catchError(err => this.restExtractor.redirectTo404IfNotFound(err, 'other', [ | |
54 | HttpStatusCode.BAD_REQUEST_400, | |
55 | HttpStatusCode.NOT_FOUND_404 | |
56 | ])) | |
57 | ) | |
58 | .subscribe(async videoChannel => { | |
59 | this.channelDescriptionHTML = await this.markdown.textMarkdownToHTML(videoChannel.description) | |
60 | this.ownerDescriptionHTML = await this.markdown.textMarkdownToHTML(videoChannel.ownerAccount.description) | |
61 | ||
62 | // After the markdown renderer to avoid layout changes | |
63 | this.videoChannel = videoChannel | |
64 | this.ownerAccount = new Account(this.videoChannel.ownerAccount) | |
65 | ||
66 | this.loadChannelVideosCount() | |
67 | this.loadOwnerBlockStatus() | |
68 | }) | |
69 | ||
70 | this.hotkeys = [ | |
71 | new Hotkey('S', (event: KeyboardEvent): boolean => { | |
72 | if (this.subscribeButton.subscribed) this.subscribeButton.unsubscribe() | |
73 | else this.subscribeButton.subscribe() | |
74 | ||
75 | return false | |
76 | }, undefined, $localize`Subscribe to the account`) | |
77 | ] | |
78 | if (this.isUserLoggedIn()) this.hotkeysService.add(this.hotkeys) | |
79 | ||
80 | this.links = [ | |
81 | { label: $localize`VIDEOS`, routerLink: 'videos' }, | |
82 | { label: $localize`PLAYLISTS`, routerLink: 'video-playlists' } | |
83 | ] | |
84 | } | |
85 | ||
86 | ngOnDestroy () { | |
87 | if (this.routeSub) this.routeSub.unsubscribe() | |
88 | ||
89 | // Unbind hotkeys | |
90 | if (this.isUserLoggedIn()) this.hotkeysService.remove(this.hotkeys) | |
91 | } | |
92 | ||
93 | isInSmallView () { | |
94 | return this.screenService.isInSmallView() | |
95 | } | |
96 | ||
97 | isUserLoggedIn () { | |
98 | return this.authService.isLoggedIn() | |
99 | } | |
100 | ||
101 | isOwner () { | |
102 | if (!this.isUserLoggedIn()) return false | |
103 | ||
104 | return this.videoChannel?.ownerAccount.userId === this.authService.getUser().id | |
105 | } | |
106 | ||
107 | isManageable () { | |
108 | if (!this.videoChannel.isLocal) return false | |
109 | if (!this.isUserLoggedIn()) return false | |
110 | ||
111 | return this.isOwner() || this.authService.getUser().hasRight(UserRight.MANAGE_ANY_VIDEO_CHANNEL) | |
112 | } | |
113 | ||
114 | activateCopiedMessage () { | |
115 | this.notifier.success($localize`Username copied`) | |
116 | } | |
117 | ||
118 | hasShowMoreDescription () { | |
119 | return !this.channelDescriptionExpanded && this.channelDescriptionHTML.length > 100 | |
120 | } | |
121 | ||
122 | showSupportModal () { | |
123 | this.supportModal.show() | |
124 | } | |
125 | ||
126 | getAccountUrl () { | |
127 | return [ '/a', this.videoChannel.ownerBy ] | |
128 | } | |
129 | ||
130 | private loadChannelVideosCount () { | |
131 | this.videoService.getVideoChannelVideos({ | |
132 | videoChannel: this.videoChannel, | |
133 | videoPagination: { | |
134 | currentPage: 1, | |
135 | itemsPerPage: 0 | |
136 | }, | |
137 | sort: '-publishedAt' | |
138 | }).subscribe(res => this.channelVideosCount = res.total) | |
139 | } | |
140 | ||
141 | private loadOwnerBlockStatus () { | |
142 | this.blocklist.getStatus({ accounts: [ this.ownerAccount.nameWithHostForced ], hosts: [ this.ownerAccount.host ] }) | |
143 | .subscribe(status => this.ownerAccount.updateBlockStatus(status)) | |
144 | } | |
145 | } |