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