From 439f5dfc7fbbae885961085787ca185e911a83ea Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 1 Mar 2023 13:56:15 +0100 Subject: List my channels using pagination --- .../my-video-channels.component.html | 2 +- .../my-video-channels.component.ts | 132 ++++++++++++--------- 2 files changed, 77 insertions(+), 57 deletions(-) diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html index d97c35eff..5bef4a6ed 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html +++ b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html @@ -26,7 +26,7 @@
No channel found.
-
+
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channels.component.ts b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.ts index ece59c2ff..633720a6c 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channels.component.ts +++ b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.ts @@ -1,8 +1,8 @@ import { ChartData, ChartOptions, TooltipItem, TooltipModel } from 'chart.js' import { max, maxBy, min, minBy } from 'lodash-es' -import { mergeMap } from 'rxjs/operators' +import { Subject } from 'rxjs' import { Component } from '@angular/core' -import { AuthService, ConfirmService, Notifier, ScreenService } from '@app/core' +import { AuthService, ComponentPagination, ConfirmService, hasMoreItems, Notifier, ScreenService } from '@app/core' import { VideoChannel, VideoChannelService } from '@app/shared/shared-main' @Component({ @@ -15,13 +15,19 @@ export class MyVideoChannelsComponent { videoChannels: VideoChannel[] = [] videoChannelsChartData: ChartData[] - videoChannelsMinimumDailyViews = 0 - videoChannelsMaximumDailyViews: number chartOptions: ChartOptions search: string + onChannelDataSubject = new Subject() + + pagination: ComponentPagination = { + currentPage: 1, + itemsPerPage: 10, + totalItems: null + } + constructor ( private authService: AuthService, private notifier: Notifier, @@ -36,7 +42,12 @@ export class MyVideoChannelsComponent { onSearch (search: string) { this.search = search - this.loadVideoChannels() + + this.pagination.currentPage = 1 + this.videoChannels = [] + + this.authService.userInformationLoaded + .subscribe(() => this.loadMoreVideoChannels()) } async deleteVideoChannel (videoChannel: VideoChannel) { @@ -56,7 +67,7 @@ channel with the same name (${videoChannel.name})!`, this.videoChannelService.removeVideoChannel(videoChannel) .subscribe({ next: () => { - this.loadVideoChannels() + this.videoChannels = this.videoChannels.filter(c => c.id !== videoChannel.id) this.notifier.success($localize`Video channel ${videoChannel.displayName} deleted.`) }, @@ -64,58 +75,67 @@ channel with the same name (${videoChannel.name})!`, }) } - private loadVideoChannels () { - this.authService.userInformationLoaded - .pipe(mergeMap(() => { - const user = this.authService.getUser() - const options = { - account: user.account, - withStats: true, - search: this.search, - sort: '-updatedAt' - } + onNearOfBottom () { + if (!hasMoreItems(this.pagination)) return + + this.pagination.currentPage += 1 - return this.videoChannelService.listAccountVideoChannels(options) - })).subscribe(res => { - this.videoChannels = 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)) - - // 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 - this.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 - ) - - this.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 - ) - - this.buildChartOptions() - }) + 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) + }) } private buildChartOptions () { + // 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 + ) + this.chartOptions = { plugins: { legend: { @@ -141,8 +161,8 @@ channel with the same name (${videoChannel.name})!`, }, y: { display: false, - min: Math.max(0, this.videoChannelsMinimumDailyViews - (3 * this.videoChannelsMaximumDailyViews / 100)), - max: Math.max(1, this.videoChannelsMaximumDailyViews) + min: Math.max(0, videoChannelsMinimumDailyViews - (3 * videoChannelsMaximumDailyViews / 100)), + max: Math.max(1, videoChannelsMaximumDailyViews) } }, layout: { -- cgit v1.2.3