]>
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({ | |
60 | markdown: videoChannel.description, | |
61 | withEmoji: true, | |
62 | withHtml: true | |
63 | }) | |
64 | ||
65 | this.ownerDescriptionHTML = await this.markdown.textMarkdownToHTML({ | |
66 | markdown: videoChannel.ownerAccount.description, | |
67 | withEmoji: true, | |
68 | withHtml: true | |
69 | }) | |
70 | ||
71 | // After the markdown renderer to avoid layout changes | |
72 | this.videoChannel = videoChannel | |
73 | this.ownerAccount = new Account(this.videoChannel.ownerAccount) | |
74 | ||
75 | this.loadChannelVideosCount() | |
76 | this.loadOwnerBlockStatus() | |
77 | }) | |
78 | ||
79 | this.hotkeys = [ | |
80 | new Hotkey('S', (event: KeyboardEvent): boolean => { | |
81 | if (this.subscribeButton.subscribed) this.subscribeButton.unsubscribe() | |
82 | else this.subscribeButton.subscribe() | |
83 | ||
84 | return false | |
85 | }, undefined, $localize`Subscribe to the account`) | |
86 | ] | |
87 | if (this.isUserLoggedIn()) this.hotkeysService.add(this.hotkeys) | |
88 | ||
89 | this.links = [ | |
90 | { label: $localize`VIDEOS`, routerLink: 'videos' }, | |
91 | { label: $localize`PLAYLISTS`, routerLink: 'video-playlists' } | |
92 | ] | |
93 | } | |
94 | ||
95 | ngOnDestroy () { | |
96 | if (this.routeSub) this.routeSub.unsubscribe() | |
97 | ||
98 | // Unbind hotkeys | |
99 | if (this.isUserLoggedIn()) this.hotkeysService.remove(this.hotkeys) | |
100 | } | |
101 | ||
102 | isInSmallView () { | |
103 | return this.screenService.isInSmallView() | |
104 | } | |
105 | ||
106 | isUserLoggedIn () { | |
107 | return this.authService.isLoggedIn() | |
108 | } | |
109 | ||
110 | isOwner () { | |
111 | if (!this.isUserLoggedIn()) return false | |
112 | ||
113 | return this.videoChannel?.ownerAccount.userId === this.authService.getUser().id | |
114 | } | |
115 | ||
116 | isManageable () { | |
117 | if (!this.videoChannel.isLocal) return false | |
118 | if (!this.isUserLoggedIn()) return false | |
119 | ||
120 | return this.isOwner() || this.authService.getUser().hasRight(UserRight.MANAGE_ANY_VIDEO_CHANNEL) | |
121 | } | |
122 | ||
123 | activateCopiedMessage () { | |
124 | this.notifier.success($localize`Username copied`) | |
125 | } | |
126 | ||
127 | hasShowMoreDescription () { | |
128 | return !this.channelDescriptionExpanded && this.channelDescriptionHTML.length > 100 | |
129 | } | |
130 | ||
131 | showSupportModal () { | |
132 | this.supportModal.show() | |
133 | } | |
134 | ||
135 | getAccountUrl () { | |
136 | return [ '/a', this.videoChannel.ownerBy ] | |
137 | } | |
138 | ||
139 | private loadChannelVideosCount () { | |
140 | this.videoService.getVideoChannelVideos({ | |
141 | videoChannel: this.videoChannel, | |
142 | videoPagination: { | |
143 | currentPage: 1, | |
144 | itemsPerPage: 0 | |
145 | }, | |
146 | sort: '-publishedAt' | |
147 | }).subscribe(res => this.channelVideosCount = res.total) | |
148 | } | |
149 | ||
150 | private loadOwnerBlockStatus () { | |
151 | this.blocklist.getStatus({ accounts: [ this.ownerAccount.nameWithHostForced ], hosts: [ this.ownerAccount.host ] }) | |
152 | .subscribe(status => this.ownerAccount.updateBlockStatus(status)) | |
153 | } | |
154 | } |