diff options
author | Chocobozzz <me@florianbigard.com> | 2020-06-23 14:10:17 +0200 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2020-06-23 16:00:49 +0200 |
commit | 67ed6552b831df66713bac9e672738796128d33f (patch) | |
tree | 59c97d41e0b49d75a90aa3de987968ab9b1ff447 /client/src/app/shared/shared-user-subscription/subscribe-button.component.ts | |
parent | 0c4bacbff53bc732f5a2677d62a6ead7752e2405 (diff) | |
download | PeerTube-67ed6552b831df66713bac9e672738796128d33f.tar.gz PeerTube-67ed6552b831df66713bac9e672738796128d33f.tar.zst PeerTube-67ed6552b831df66713bac9e672738796128d33f.zip |
Reorganize client shared modules
Diffstat (limited to 'client/src/app/shared/shared-user-subscription/subscribe-button.component.ts')
-rw-r--r-- | client/src/app/shared/shared-user-subscription/subscribe-button.component.ts | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/client/src/app/shared/shared-user-subscription/subscribe-button.component.ts b/client/src/app/shared/shared-user-subscription/subscribe-button.component.ts new file mode 100644 index 000000000..72fa3f4fd --- /dev/null +++ b/client/src/app/shared/shared-user-subscription/subscribe-button.component.ts | |||
@@ -0,0 +1,196 @@ | |||
1 | import { concat, forkJoin, merge } from 'rxjs' | ||
2 | import { Component, Input, OnChanges, OnInit } from '@angular/core' | ||
3 | import { Router } from '@angular/router' | ||
4 | import { AuthService, Notifier } from '@app/core' | ||
5 | import { Account, VideoChannel, VideoService } from '@app/shared/shared-main' | ||
6 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
7 | import { FeedFormat } from '@shared/models' | ||
8 | import { UserSubscriptionService } from './user-subscription.service' | ||
9 | |||
10 | @Component({ | ||
11 | selector: 'my-subscribe-button', | ||
12 | templateUrl: './subscribe-button.component.html', | ||
13 | styleUrls: [ './subscribe-button.component.scss' ] | ||
14 | }) | ||
15 | export class SubscribeButtonComponent implements OnInit, OnChanges { | ||
16 | /** | ||
17 | * SubscribeButtonComponent can be used with a single VideoChannel passed as [VideoChannel], | ||
18 | * or with an account and a full list of that account's videoChannels. The latter is intended | ||
19 | * to allow mass un/subscription from an account's page, while keeping the channel-centric | ||
20 | * subscription model. | ||
21 | */ | ||
22 | @Input() account: Account | ||
23 | @Input() videoChannels: VideoChannel[] | ||
24 | @Input() displayFollowers = false | ||
25 | @Input() size: 'small' | 'normal' = 'normal' | ||
26 | |||
27 | subscribed = new Map<string, boolean>() | ||
28 | |||
29 | constructor ( | ||
30 | private authService: AuthService, | ||
31 | private router: Router, | ||
32 | private notifier: Notifier, | ||
33 | private userSubscriptionService: UserSubscriptionService, | ||
34 | private i18n: I18n, | ||
35 | private videoService: VideoService | ||
36 | ) { } | ||
37 | |||
38 | get handle () { | ||
39 | return this.account | ||
40 | ? this.account.nameWithHost | ||
41 | : this.videoChannel.name + '@' + this.videoChannel.host | ||
42 | } | ||
43 | |||
44 | get channelHandle () { | ||
45 | return this.getChannelHandler(this.videoChannel) | ||
46 | } | ||
47 | |||
48 | get uri () { | ||
49 | return this.account | ||
50 | ? this.account.url | ||
51 | : this.videoChannels[0].url | ||
52 | } | ||
53 | |||
54 | get rssUri () { | ||
55 | const rssFeed = this.account | ||
56 | ? this.videoService | ||
57 | .getAccountFeedUrls(this.account.id) | ||
58 | .find(i => i.format === FeedFormat.RSS) | ||
59 | : this.videoService | ||
60 | .getVideoChannelFeedUrls(this.videoChannels[0].id) | ||
61 | .find(i => i.format === FeedFormat.RSS) | ||
62 | |||
63 | return rssFeed.url | ||
64 | } | ||
65 | |||
66 | get videoChannel () { | ||
67 | return this.videoChannels[0] | ||
68 | } | ||
69 | |||
70 | get isAllChannelsSubscribed () { | ||
71 | return this.subscribeStatus(true).length === this.videoChannels.length | ||
72 | } | ||
73 | |||
74 | get isAtLeastOneChannelSubscribed () { | ||
75 | return this.subscribeStatus(true).length > 0 | ||
76 | } | ||
77 | |||
78 | get isBigButton () { | ||
79 | return this.isUserLoggedIn() && this.videoChannels.length > 1 && this.isAtLeastOneChannelSubscribed | ||
80 | } | ||
81 | |||
82 | ngOnInit () { | ||
83 | this.loadSubscribedStatus() | ||
84 | } | ||
85 | |||
86 | ngOnChanges () { | ||
87 | this.ngOnInit() | ||
88 | } | ||
89 | |||
90 | subscribe () { | ||
91 | if (this.isUserLoggedIn()) { | ||
92 | return this.localSubscribe() | ||
93 | } | ||
94 | |||
95 | return this.gotoLogin() | ||
96 | } | ||
97 | |||
98 | localSubscribe () { | ||
99 | const subscribedStatus = this.subscribeStatus(false) | ||
100 | |||
101 | const observableBatch = this.videoChannels | ||
102 | .map(videoChannel => this.getChannelHandler(videoChannel)) | ||
103 | .filter(handle => subscribedStatus.includes(handle)) | ||
104 | .map(handle => this.userSubscriptionService.addSubscription(handle)) | ||
105 | |||
106 | forkJoin(observableBatch) | ||
107 | .subscribe( | ||
108 | () => { | ||
109 | this.notifier.success( | ||
110 | this.account | ||
111 | ? this.i18n( | ||
112 | 'Subscribed to all current channels of {{nameWithHost}}. You will be notified of all their new videos.', | ||
113 | { nameWithHost: this.account.displayName } | ||
114 | ) | ||
115 | : this.i18n( | ||
116 | 'Subscribed to {{nameWithHost}}. You will be notified of all their new videos.', | ||
117 | { nameWithHost: this.videoChannels[0].displayName } | ||
118 | ) | ||
119 | , | ||
120 | this.i18n('Subscribed') | ||
121 | ) | ||
122 | }, | ||
123 | |||
124 | err => this.notifier.error(err.message) | ||
125 | ) | ||
126 | } | ||
127 | |||
128 | unsubscribe () { | ||
129 | if (this.isUserLoggedIn()) { | ||
130 | this.localUnsubscribe() | ||
131 | } | ||
132 | } | ||
133 | |||
134 | localUnsubscribe () { | ||
135 | const subscribeStatus = this.subscribeStatus(true) | ||
136 | |||
137 | const observableBatch = this.videoChannels | ||
138 | .map(videoChannel => this.getChannelHandler(videoChannel)) | ||
139 | .filter(handle => subscribeStatus.includes(handle)) | ||
140 | .map(handle => this.userSubscriptionService.deleteSubscription(handle)) | ||
141 | |||
142 | concat(...observableBatch) | ||
143 | .subscribe({ | ||
144 | complete: () => { | ||
145 | this.notifier.success( | ||
146 | this.account | ||
147 | ? this.i18n('Unsubscribed from all channels of {{nameWithHost}}', { nameWithHost: this.account.nameWithHost }) | ||
148 | : this.i18n('Unsubscribed from {{nameWithHost}}', { nameWithHost: this.videoChannels[ 0 ].nameWithHost }) | ||
149 | , | ||
150 | this.i18n('Unsubscribed') | ||
151 | ) | ||
152 | }, | ||
153 | |||
154 | error: err => this.notifier.error(err.message) | ||
155 | }) | ||
156 | } | ||
157 | |||
158 | isUserLoggedIn () { | ||
159 | return this.authService.isLoggedIn() | ||
160 | } | ||
161 | |||
162 | gotoLogin () { | ||
163 | this.router.navigate([ '/login' ]) | ||
164 | } | ||
165 | |||
166 | subscribeStatus (subscribed: boolean) { | ||
167 | const accumulator: string[] = [] | ||
168 | for (const [key, value] of this.subscribed.entries()) { | ||
169 | if (value === subscribed) accumulator.push(key) | ||
170 | } | ||
171 | |||
172 | return accumulator | ||
173 | } | ||
174 | |||
175 | private getChannelHandler (videoChannel: VideoChannel) { | ||
176 | return videoChannel.name + '@' + videoChannel.host | ||
177 | } | ||
178 | |||
179 | private loadSubscribedStatus () { | ||
180 | if (!this.isUserLoggedIn()) return | ||
181 | |||
182 | for (const videoChannel of this.videoChannels) { | ||
183 | const handle = this.getChannelHandler(videoChannel) | ||
184 | this.subscribed.set(handle, false) | ||
185 | |||
186 | merge( | ||
187 | this.userSubscriptionService.listenToSubscriptionCacheChange(handle), | ||
188 | this.userSubscriptionService.doesSubscriptionExist(handle) | ||
189 | ).subscribe( | ||
190 | res => this.subscribed.set(handle, res), | ||
191 | |||
192 | err => this.notifier.error(err.message) | ||
193 | ) | ||
194 | } | ||
195 | } | ||
196 | } | ||