Fix client build
[oweals/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, merge } 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 = new 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
40   get handle () {
41     return this.account
42       ? this.account.nameWithHost
43       : this.videoChannel.name + '@' + this.videoChannel.host
44   }
45
46   get channelHandle () {
47     return this.getChannelHandler(this.videoChannel)
48   }
49
50   get uri () {
51     return this.account
52       ? this.account.url
53       : this.videoChannels[0].url
54   }
55
56   get rssUri () {
57     const rssFeed = this.account
58       ? this.videoService
59           .getAccountFeedUrls(this.account.id)
60           .find(i => i.format === FeedFormat.RSS)
61       : this.videoService
62           .getVideoChannelFeedUrls(this.videoChannels[0].id)
63           .find(i => i.format === FeedFormat.RSS)
64
65     return rssFeed.url
66   }
67
68   get videoChannel () {
69     return this.videoChannels[0]
70   }
71
72   ngOnInit () {
73     this.loadSubscribedStatus()
74   }
75
76   subscribe () {
77     if (this.isUserLoggedIn()) {
78       return this.localSubscribe()
79     }
80
81     return this.gotoLogin()
82   }
83
84   localSubscribe () {
85     const observableBatch = this.videoChannels
86       .map(videoChannel => this.getChannelHandler(videoChannel))
87       .filter(handle => this.subscribeStatus(false).includes(handle))
88       .map(handle => this.userSubscriptionService.addSubscription(handle))
89
90     merge(observableBatch, 2)
91       .subscribe(
92         () => {
93           this.notifier.success(
94             this.account
95               ? this.i18n(
96                   'Subscribed to all current channels of {{nameWithHost}}. You will be notified of all their new videos.',
97                   { nameWithHost: this.account.displayName }
98                 )
99               : this.i18n(
100                   'Subscribed to {{nameWithHost}}. You will be notified of all their new videos.',
101                   { nameWithHost: this.videoChannels[0].displayName }
102                 )
103             ,
104             this.i18n('Subscribed')
105           )
106         },
107
108           err => this.notifier.error(err.message)
109       )
110   }
111
112   unsubscribe () {
113     if (this.isUserLoggedIn()) {
114       this.localUnsubscribe()
115     }
116   }
117
118   localUnsubscribe () {
119     const observableBatch = this.videoChannels
120       .map(videoChannel => this.getChannelHandler(videoChannel))
121       .filter(handle => this.subscribeStatus(true).includes(handle))
122       .map(handle => this.userSubscriptionService.deleteSubscription(handle))
123
124     forkJoin(observableBatch)
125         .subscribe(
126           () => {
127             this.notifier.success(
128               this.account
129                 ? this.i18n('Unsubscribed from all channels of {{nameWithHost}}', { nameWithHost: this.account.nameWithHost })
130                 : this.i18n('Unsubscribed from {{nameWithHost}}', { nameWithHost: this.videoChannels[0].nameWithHost })
131               ,
132               this.i18n('Unsubscribed')
133             )
134           },
135
136           err => this.notifier.error(err.message)
137         )
138   }
139
140   isUserLoggedIn () {
141     return this.authService.isLoggedIn()
142   }
143
144   isAllChannelsSubscribed () {
145     return !Array.from(this.subscribed.values()).includes(false)
146   }
147
148   isAtLeastOneChannelSubscribed () {
149     return this.subscribeStatus(true).length > 0
150   }
151
152   isBigButton () {
153     return this.isUserLoggedIn() && this.videoChannels.length > 1 && this.isAtLeastOneChannelSubscribed()
154   }
155
156   gotoLogin () {
157     this.router.navigate([ '/login' ])
158   }
159
160   subscribeStatus (subscribed: boolean) {
161     const accumulator: string[] = []
162     for (const [key, value] of this.subscribed.entries()) {
163       if (value === subscribed) accumulator.push(key)
164     }
165
166     return accumulator
167   }
168
169   private getChannelHandler (videoChannel: VideoChannel) {
170     return videoChannel.name + '@' + videoChannel.host
171   }
172
173   private loadSubscribedStatus () {
174     if (!this.isUserLoggedIn()) return
175
176     for (const videoChannel of this.videoChannels) {
177       const handle = this.getChannelHandler(videoChannel)
178       this.subscribed.set(handle, false)
179       merge(
180         this.userSubscriptionService.listenToSubscriptionCacheChange(handle),
181         this.userSubscriptionService.doesSubscriptionExist(handle)
182       )
183           .subscribe(
184             res => this.subscribed.set(handle, res),
185
186             err => this.notifier.error(err.message)
187           )
188     }
189   }
190 }