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