2021-08-26 09:00:08 +02:00
import { ChartData , ChartOptions , TooltipItem , TooltipModel } from 'chart.js'
2020-06-23 14:10:17 +02:00
import { max , maxBy , min , minBy } from 'lodash-es'
2023-03-01 13:56:15 +01:00
import { Subject } from 'rxjs'
2021-05-03 14:33:34 +02:00
import { Component } from '@angular/core'
2023-03-01 13:56:15 +01:00
import { AuthService , ComponentPagination , ConfirmService , hasMoreItems , Notifier , ScreenService } from '@app/core'
2020-06-23 14:10:17 +02:00
import { VideoChannel , VideoChannelService } from '@app/shared/shared-main'
2023-08-18 14:12:32 +02:00
import { formatICU } from '@app/helpers'
2018-04-26 16:11:38 +02:00
@Component ( {
2020-11-12 15:28:54 +01:00
templateUrl : './my-video-channels.component.html' ,
styleUrls : [ './my-video-channels.component.scss' ]
2018-04-26 16:11:38 +02:00
} )
2021-05-03 14:33:34 +02:00
export class MyVideoChannelsComponent {
2020-07-23 21:30:04 +02:00
totalItems : number
2018-04-26 16:11:38 +02:00
videoChannels : VideoChannel [ ] = [ ]
2021-05-03 14:33:34 +02:00
2020-03-30 12:06:46 +02:00
videoChannelsChartData : ChartData [ ]
2018-04-26 16:11:38 +02:00
2021-08-26 09:00:08 +02:00
chartOptions : ChartOptions
2020-11-19 11:12:01 +01:00
2021-05-03 14:33:34 +02:00
search : string
2018-04-26 16:11:38 +02:00
2023-03-01 13:56:15 +01:00
onChannelDataSubject = new Subject < any > ( )
pagination : ComponentPagination = {
currentPage : 1 ,
itemsPerPage : 10 ,
totalItems : null
}
2018-04-26 16:11:38 +02:00
constructor (
private authService : AuthService ,
2018-12-19 16:04:34 +01:00
private notifier : Notifier ,
2018-04-26 16:11:38 +02:00
private confirmService : ConfirmService ,
2018-06-04 16:21:17 +02:00
private videoChannelService : VideoChannelService ,
2020-08-12 10:40:04 +02:00
private screenService : ScreenService
2021-05-03 14:33:34 +02:00
) { }
2018-04-26 16:11:38 +02:00
2020-03-23 10:14:05 +01:00
get isInSmallView ( ) {
return this . screenService . isInSmallView ( )
}
2021-05-03 14:33:34 +02:00
onSearch ( search : string ) {
this . search = search
2023-03-01 13:56:15 +01:00
this . pagination . currentPage = 1
this . videoChannels = [ ]
this . authService . userInformationLoaded
. subscribe ( ( ) = > this . loadMoreVideoChannels ( ) )
2020-07-23 21:30:04 +02:00
}
2018-04-26 16:11:38 +02:00
async deleteVideoChannel ( videoChannel : VideoChannel ) {
2022-10-07 11:06:28 +02:00
const res = await this . confirmService . confirmWithExpectedInput (
2023-08-18 14:12:32 +02:00
$localize ` Do you really want to delete ${ videoChannel . displayName } ? ` +
` <br /> ` +
formatICU (
// eslint-disable-next-line max-len
$localize ` It will delete {count, plural, =1 {1 video} other {{count} videos}} uploaded in this channel, and you will not be able to create another channel or account with the same name ( ${ videoChannel . name } )! ` ,
{ count : videoChannel.videosCount }
) ,
2020-08-12 10:40:04 +02:00
2021-07-20 13:38:26 +02:00
$localize ` Please type the name of the video channel ( ${ videoChannel . name } ) to confirm ` ,
2020-08-12 10:40:04 +02:00
2021-07-20 13:38:26 +02:00
videoChannel . name ,
2020-11-10 10:52:05 +01:00
2020-08-12 10:40:04 +02:00
$localize ` Delete `
2018-04-26 16:11:38 +02:00
)
if ( res === false ) return
this . videoChannelService . removeVideoChannel ( videoChannel )
2021-08-17 11:27:47 +02:00
. subscribe ( {
next : ( ) = > {
2023-03-01 13:56:15 +01:00
this . videoChannels = this . videoChannels . filter ( c = > c . id !== videoChannel . id )
2020-08-12 10:40:04 +02:00
this . notifier . success ( $localize ` Video channel ${ videoChannel . displayName } deleted. ` )
2018-04-26 16:11:38 +02:00
} ,
2021-08-17 11:27:47 +02:00
error : err = > this . notifier . error ( err . message )
} )
2018-04-26 16:11:38 +02:00
}
2023-03-01 13:56:15 +01:00
onNearOfBottom ( ) {
if ( ! hasMoreItems ( this . pagination ) ) return
this . pagination . currentPage += 1
2021-05-10 09:31:33 +02:00
2023-03-01 13:56:15 +01:00
this . loadMoreVideoChannels ( )
}
private loadMoreVideoChannels ( ) {
const user = this . authService . getUser ( )
const options = {
account : user.account ,
withStats : true ,
search : this.search ,
componentPagination : this.pagination ,
sort : '-updatedAt'
}
return this . videoChannelService . listAccountVideoChannels ( options )
. subscribe ( res = > {
this . videoChannels = this . videoChannels . concat ( res . data )
this . totalItems = res . total
// chart data
this . videoChannelsChartData = this . videoChannels . map ( v = > ( {
labels : v.viewsPerDay.map ( day = > day . date . toLocaleDateString ( ) ) ,
datasets : [
{
label : $localize ` Views for the day ` ,
data : v.viewsPerDay.map ( day = > day . views ) ,
fill : false ,
borderColor : '#c6c6c6'
}
]
} as ChartData ) )
this . buildChartOptions ( )
this . onChannelDataSubject . next ( res . data )
} )
2018-04-26 16:11:38 +02:00
}
2020-11-19 11:12:01 +01:00
private buildChartOptions ( ) {
2023-03-01 13:56:15 +01:00
// chart options that depend on chart data:
// we don't want to skew values and have min at 0, so we define what the floor/ceiling is here
const videoChannelsMinimumDailyViews = min (
// compute local minimum daily views for each channel, by their "views" attribute
this . videoChannels . map ( v = > minBy (
v . viewsPerDay ,
day = > day . views
) . views ) // the object returned is a ViewPerDate, so we still need to get the views attribute
)
const videoChannelsMaximumDailyViews = max (
// compute local maximum daily views for each channel, by their "views" attribute
this . videoChannels . map ( v = > maxBy (
v . viewsPerDay ,
day = > day . views
) . views ) // the object returned is a ViewPerDate, so we still need to get the views attribute
)
2020-11-19 11:12:01 +01:00
this . chartOptions = {
2021-08-26 09:00:08 +02:00
plugins : {
legend : {
display : false
} ,
tooltip : {
mode : 'index' ,
intersect : false ,
external : function ( { tooltip } : { tooltip : TooltipModel < any > } ) {
if ( ! tooltip ) return
// disable displaying the color box
tooltip . options . displayColors = false
} ,
callbacks : {
label : ( tooltip : TooltipItem < any > ) = > ` ${ tooltip . formattedValue } views `
}
}
2020-11-19 11:12:01 +01:00
} ,
scales : {
2021-08-26 09:00:08 +02:00
x : {
2020-11-19 11:12:01 +01:00
display : false
2021-08-26 09:00:08 +02:00
} ,
y : {
2020-11-19 11:12:01 +01:00
display : false ,
2023-03-01 13:56:15 +01:00
min : Math.max ( 0 , videoChannelsMinimumDailyViews - ( 3 * videoChannelsMaximumDailyViews / 100 ) ) ,
max : Math.max ( 1 , videoChannelsMaximumDailyViews )
2021-08-26 09:00:08 +02:00
}
2020-11-19 11:12:01 +01:00
} ,
layout : {
padding : {
left : 15 ,
right : 15 ,
top : 10 ,
bottom : 0
}
} ,
elements : {
point : {
radius : 0
}
} ,
hover : {
mode : 'index' ,
intersect : false
}
}
}
2018-04-26 16:11:38 +02:00
}