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'
10 templateUrl: './my-video-channels.component.html',
11 styleUrls: [ './my-video-channels.component.scss' ]
13 export class MyVideoChannelsComponent implements OnInit {
16 videoChannels: VideoChannel[] = []
17 videoChannelsChartData: ChartData[]
18 videoChannelsMinimumDailyViews = 0
19 videoChannelsMaximumDailyViews: number
21 channelsSearch: string
22 channelsSearchChanged = new Subject<string>()
29 private authService: AuthService,
30 private notifier: Notifier,
31 private confirmService: ConfirmService,
32 private videoChannelService: VideoChannelService,
33 private screenService: ScreenService
37 this.user = this.authService.getUser()
39 this.loadVideoChannels()
41 this.channelsSearchChanged
42 .pipe(debounceTime(500))
44 this.loadVideoChannels()
48 get isInSmallView () {
49 return this.screenService.isInSmallView()
53 this.channelsSearch = ''
54 this.onChannelsSearchChanged()
57 onChannelsSearchChanged () {
58 this.channelsSearchChanged.next()
61 async deleteVideoChannel (videoChannel: VideoChannel) {
62 const res = await this.confirmService.confirmWithInput(
63 $localize`Do you really want to delete ${videoChannel.displayName}?
64 It will delete ${videoChannel.videosCount} videos uploaded in this channel, and you will not be able to create another
65 channel with the same name (${videoChannel.name})!`,
67 $localize`Please type the display name of the video channel (${videoChannel.displayName}) to confirm`,
69 videoChannel.displayName,
73 if (res === false) return
75 this.videoChannelService.removeVideoChannel(videoChannel)
78 this.loadVideoChannels()
79 this.notifier.success($localize`Video channel ${videoChannel.displayName} deleted.`)
82 error => this.notifier.error(error.message)
86 private loadVideoChannels () {
87 this.authService.userInformationLoaded
88 .pipe(mergeMap(() => this.videoChannelService.listAccountVideoChannels(this.user.account, null, true, this.channelsSearch)))
90 this.videoChannels = res.data
91 this.totalItems = res.total
94 this.videoChannelsChartData = this.videoChannels.map(v => ({
95 labels: v.viewsPerDay.map(day => day.date.toLocaleDateString()),
98 label: $localize`Views for the day`,
99 data: v.viewsPerDay.map(day => day.views),
101 borderColor: '#c6c6c6'
106 // chart options that depend on chart data:
107 // we don't want to skew values and have min at 0, so we define what the floor/ceiling is here
108 this.videoChannelsMinimumDailyViews = min(
109 // compute local minimum daily views for each channel, by their "views" attribute
110 this.videoChannels.map(v => minBy(
113 ).views) // the object returned is a ViewPerDate, so we still need to get the views attribute
116 this.videoChannelsMaximumDailyViews = max(
117 // compute local maximum daily views for each channel, by their "views" attribute
118 this.videoChannels.map(v => maxBy(
121 ).views) // the object returned is a ViewPerDate, so we still need to get the views attribute
124 this.buildChartOptions()
128 private buildChartOptions () {
129 this.chartOptions = {
140 min: Math.max(0, this.videoChannelsMinimumDailyViews - (3 * this.videoChannelsMaximumDailyViews / 100)),
141 max: Math.max(1, this.videoChannelsMaximumDailyViews)
161 custom: function (tooltip: any) {
163 // disable displaying the color box
164 tooltip.displayColors = false
167 label: (tooltip: any, data: any) => `${tooltip.value} views`