]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/+my-account/+my-account-video-channels/my-account-video-channels.component.ts
Fix tokens loading
[github/Chocobozzz/PeerTube.git] / client / src / app / +my-account / +my-account-video-channels / my-account-video-channels.component.ts
1 import { ChartData } from 'chart.js'
2 import { max, maxBy, min, minBy } from 'lodash-es'
3 import { Subject } from 'rxjs'
4 import { debounceTime, mergeMap } from 'rxjs/operators'
5 import { Component, OnInit } from '@angular/core'
6 import { AuthService, ConfirmService, Notifier, ScreenService, User } from '@app/core'
7 import { VideoChannel, VideoChannelService } from '@app/shared/shared-main'
8
9 @Component({
10 selector: 'my-account-video-channels',
11 templateUrl: './my-account-video-channels.component.html',
12 styleUrls: [ './my-account-video-channels.component.scss' ]
13 })
14 export class MyAccountVideoChannelsComponent implements OnInit {
15 totalItems: number
16
17 videoChannels: VideoChannel[] = []
18 videoChannelsChartData: ChartData[]
19 videoChannelsMinimumDailyViews = 0
20 videoChannelsMaximumDailyViews: number
21
22 channelsSearch: string
23 channelsSearchChanged = new Subject<string>()
24
25 private user: User
26
27 constructor (
28 private authService: AuthService,
29 private notifier: Notifier,
30 private confirmService: ConfirmService,
31 private videoChannelService: VideoChannelService,
32 private screenService: ScreenService
33 ) {}
34
35 ngOnInit () {
36 this.user = this.authService.getUser()
37
38 this.loadVideoChannels()
39
40 this.channelsSearchChanged
41 .pipe(debounceTime(500))
42 .subscribe(() => {
43 this.loadVideoChannels()
44 })
45 }
46
47 get isInSmallView () {
48 return this.screenService.isInSmallView()
49 }
50
51 get chartOptions () {
52 return {
53 legend: {
54 display: false
55 },
56 scales: {
57 xAxes: [{
58 display: false
59 }],
60 yAxes: [{
61 display: false,
62 ticks: {
63 min: Math.max(0, this.videoChannelsMinimumDailyViews - (3 * this.videoChannelsMaximumDailyViews / 100)),
64 max: Math.max(1, this.videoChannelsMaximumDailyViews)
65 }
66 }]
67 },
68 layout: {
69 padding: {
70 left: 15,
71 right: 15,
72 top: 10,
73 bottom: 0
74 }
75 },
76 elements: {
77 point: {
78 radius: 0
79 }
80 },
81 tooltips: {
82 mode: 'index',
83 intersect: false,
84 custom: function (tooltip: any) {
85 if (!tooltip) return
86 // disable displaying the color box
87 tooltip.displayColors = false
88 },
89 callbacks: {
90 label: (tooltip: any, data: any) => `${tooltip.value} views`
91 }
92 },
93 hover: {
94 mode: 'index',
95 intersect: false
96 }
97 }
98 }
99
100 resetSearch () {
101 this.channelsSearch = ''
102 this.onChannelsSearchChanged()
103 }
104
105 onChannelsSearchChanged () {
106 this.channelsSearchChanged.next()
107 }
108
109 async deleteVideoChannel (videoChannel: VideoChannel) {
110 const res = await this.confirmService.confirmWithInput(
111 $localize`Do you really want to delete ${videoChannel.displayName}?
112 It will delete ${videoChannel.videosCount} videos uploaded in this channel, and you will not be able to create another
113 channel with the same name (${videoChannel.name})!`,
114
115 $localize`Please type the display name of the video channel (${videoChannel.displayName}) to confirm`,
116
117 $localize`Delete`
118 )
119 if (res === false) return
120
121 this.videoChannelService.removeVideoChannel(videoChannel)
122 .subscribe(
123 () => {
124 this.loadVideoChannels()
125 this.notifier.success($localize`Video channel ${videoChannel.displayName} deleted.`)
126 },
127
128 error => this.notifier.error(error.message)
129 )
130 }
131
132 private loadVideoChannels () {
133 this.authService.userInformationLoaded
134 .pipe(mergeMap(() => this.videoChannelService.listAccountVideoChannels(this.user.account, null, true, this.channelsSearch)))
135 .subscribe(res => {
136 this.videoChannels = res.data
137 this.totalItems = res.total
138
139 // chart data
140 this.videoChannelsChartData = this.videoChannels.map(v => ({
141 labels: v.viewsPerDay.map(day => day.date.toLocaleDateString()),
142 datasets: [
143 {
144 label: $localize`Views for the day`,
145 data: v.viewsPerDay.map(day => day.views),
146 fill: false,
147 borderColor: '#c6c6c6'
148 }
149 ]
150 } as ChartData))
151
152 // chart options that depend on chart data:
153 // we don't want to skew values and have min at 0, so we define what the floor/ceiling is here
154 this.videoChannelsMinimumDailyViews = min(
155 // compute local minimum daily views for each channel, by their "views" attribute
156 this.videoChannels.map(v => minBy(
157 v.viewsPerDay,
158 day => day.views
159 ).views) // the object returned is a ViewPerDate, so we still need to get the views attribute
160 )
161 this.videoChannelsMaximumDailyViews = max(
162 // compute local maximum daily views for each channel, by their "views" attribute
163 this.videoChannels.map(v => maxBy(
164 v.viewsPerDay,
165 day => day.views
166 ).views) // the object returned is a ViewPerDate, so we still need to get the views attribute
167 )
168 })
169 }
170 }