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