From 384ba8b77a8e4805c099f5ea12b41c2ca5776e26 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 5 Apr 2022 14:03:52 +0200 Subject: Support videos stats in client --- .../shared/shared-icons/global-icon.component.ts | 3 ++- .../shared-main/angular/number-formatter.pipe.ts | 1 + .../app/shared/shared-main/shared-main.module.ts | 3 ++- client/src/app/shared/shared-main/video/index.ts | 1 + .../app/shared/shared-main/video/video.model.ts | 11 +++++++---- .../app/shared/shared-main/video/video.resolver.ts | 17 ++++++++++++++++ .../app/shared/shared-main/video/video.service.ts | 4 ---- .../video-actions-dropdown.component.ts | 17 +++++++++++++++- .../video-miniature.component.ts | 23 ++++++++++++---------- 9 files changed, 59 insertions(+), 21 deletions(-) create mode 100644 client/src/app/shared/shared-main/video/video.resolver.ts (limited to 'client/src/app/shared') diff --git a/client/src/app/shared/shared-icons/global-icon.component.ts b/client/src/app/shared/shared-icons/global-icon.component.ts index a4c62c234..ba23edde0 100644 --- a/client/src/app/shared/shared-icons/global-icon.component.ts +++ b/client/src/app/shared/shared-icons/global-icon.component.ts @@ -75,7 +75,8 @@ const icons = { 'chevrons-up': require('!!raw-loader?!../../../assets/images/feather/chevrons-up.svg').default, 'message-circle': require('!!raw-loader?!../../../assets/images/feather/message-circle.svg').default, codesandbox: require('!!raw-loader?!../../../assets/images/feather/codesandbox.svg').default, - award: require('!!raw-loader?!../../../assets/images/feather/award.svg').default + award: require('!!raw-loader?!../../../assets/images/feather/award.svg').default, + stats: require('!!raw-loader?!../../../assets/images/feather/stats.svg').default } export type GlobalIconName = keyof typeof icons diff --git a/client/src/app/shared/shared-main/angular/number-formatter.pipe.ts b/client/src/app/shared/shared-main/angular/number-formatter.pipe.ts index 8badb1573..7c18b7f67 100644 --- a/client/src/app/shared/shared-main/angular/number-formatter.pipe.ts +++ b/client/src/app/shared/shared-main/angular/number-formatter.pipe.ts @@ -22,6 +22,7 @@ export class NumberFormatterPipe implements PipeTransform { { max: 1000000, type: 'K' }, { max: 1000000000, type: 'M' } ] + constructor (@Inject(LOCALE_ID) private localeId: string) {} transform (value: number) { diff --git a/client/src/app/shared/shared-main/shared-main.module.ts b/client/src/app/shared/shared-main/shared-main.module.ts index d83af9a66..5629640bc 100644 --- a/client/src/app/shared/shared-main/shared-main.module.ts +++ b/client/src/app/shared/shared-main/shared-main.module.ts @@ -45,7 +45,7 @@ import { import { PluginPlaceholderComponent, PluginSelectorDirective } from './plugins' import { ActorRedirectGuard } from './router' import { UserHistoryService, UserNotificationsComponent, UserNotificationService, UserQuotaComponent } from './users' -import { EmbedComponent, RedundancyService, VideoImportService, VideoOwnershipService, VideoService } from './video' +import { EmbedComponent, RedundancyService, VideoImportService, VideoOwnershipService, VideoResolver, VideoService } from './video' import { VideoCaptionService } from './video-caption' import { VideoChannelService } from './video-channel' @@ -190,6 +190,7 @@ import { VideoChannelService } from './video-channel' VideoImportService, VideoOwnershipService, VideoService, + VideoResolver, VideoCaptionService, diff --git a/client/src/app/shared/shared-main/video/index.ts b/client/src/app/shared/shared-main/video/index.ts index e72c0c3d6..361601456 100644 --- a/client/src/app/shared/shared-main/video/index.ts +++ b/client/src/app/shared/shared-main/video/index.ts @@ -5,4 +5,5 @@ export * from './video-edit.model' export * from './video-import.service' export * from './video-ownership.service' export * from './video.model' +export * from './video.resolver' export * from './video.service' diff --git a/client/src/app/shared/shared-main/video/video.model.ts b/client/src/app/shared/shared-main/video/video.model.ts index 2d4db9a28..022bb95ad 100644 --- a/client/src/app/shared/shared-main/video/video.model.ts +++ b/client/src/app/shared/shared-main/video/video.model.ts @@ -58,8 +58,7 @@ export class Video implements VideoServerModel { url: string views: number - // If live - viewers?: number + viewers: number likes: number dislikes: number @@ -234,9 +233,13 @@ export class Video implements VideoServerModel { this.isUpdatableBy(user) } + canSeeStats (user: AuthUser) { + return user && this.isLocal === true && (this.account.name === user.username || user.hasRight(UserRight.SEE_ALL_VIDEOS)) + } + canRemoveFiles (user: AuthUser) { return this.isLocal && - user.hasRight(UserRight.MANAGE_VIDEO_FILES) && + user && user.hasRight(UserRight.MANAGE_VIDEO_FILES) && this.state.id !== VideoState.TO_TRANSCODE && this.hasHLS() && this.hasWebTorrent() @@ -244,7 +247,7 @@ export class Video implements VideoServerModel { canRunTranscoding (user: AuthUser) { return this.isLocal && - user.hasRight(UserRight.RUN_VIDEO_TRANSCODING) && + user && user.hasRight(UserRight.RUN_VIDEO_TRANSCODING) && this.state.id !== VideoState.TO_TRANSCODE } diff --git a/client/src/app/shared/shared-main/video/video.resolver.ts b/client/src/app/shared/shared-main/video/video.resolver.ts new file mode 100644 index 000000000..65b7230ce --- /dev/null +++ b/client/src/app/shared/shared-main/video/video.resolver.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@angular/core' +import { ActivatedRouteSnapshot, Resolve } from '@angular/router' +import { VideoService } from './video.service' + +@Injectable() +export class VideoResolver implements Resolve { + constructor ( + private videoService: VideoService + ) { + } + + resolve (route: ActivatedRouteSnapshot) { + const videoId: string = route.params['videoId'] + + return this.videoService.getVideo({ videoId }) + } +} diff --git a/client/src/app/shared/shared-main/video/video.service.ts b/client/src/app/shared/shared-main/video/video.service.ts index 94af9cd38..bc15c326f 100644 --- a/client/src/app/shared/shared-main/video/video.service.ts +++ b/client/src/app/shared/shared-main/video/video.service.ts @@ -65,10 +65,6 @@ export class VideoService { return `${VideoService.BASE_VIDEO_URL}/${uuid}/views` } - getUserWatchingVideoUrl (uuid: string) { - return `${VideoService.BASE_VIDEO_URL}/${uuid}/watching` - } - getVideo (options: { videoId: string }): Observable { return this.serverService.getServerLocale() .pipe( diff --git a/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts b/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts index 5eef96145..ed6a4afc0 100644 --- a/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts +++ b/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts @@ -30,6 +30,7 @@ export type VideoActionsDisplayType = { removeFiles?: boolean transcoding?: boolean studio?: boolean + stats?: boolean } @Component({ @@ -61,9 +62,11 @@ export class VideoActionsDropdownComponent implements OnChanges { liveInfo: false, removeFiles: false, transcoding: false, - studio: true + studio: true, + stats: true } @Input() placement = 'left' + @Input() moreActions: DropdownAction<{ video: Video }>[][] = [] @Input() label: string @@ -156,6 +159,10 @@ export class VideoActionsDropdownComponent implements OnChanges { return this.video.isEditableBy(this.user, this.serverService.getHTMLConfig().videoStudio.enabled) } + isVideoStatsAvailable () { + return this.video.canSeeStats(this.user) + } + isVideoRemovable () { return this.video.isRemovableBy(this.user) } @@ -342,6 +349,12 @@ export class VideoActionsDropdownComponent implements OnChanges { iconName: 'film', isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.studio && this.isVideoEditable() }, + { + label: $localize`Stats`, + linkBuilder: ({ video }) => [ '/stats/videos', video.uuid ], + iconName: 'stats', + isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.stats && this.isVideoStatsAvailable() + }, { label: $localize`Block`, handler: () => this.showBlockModal(), @@ -408,5 +421,7 @@ export class VideoActionsDropdownComponent implements OnChanges { } ] ] + + this.videoActions = this.videoActions.concat(this.moreActions) } } diff --git a/client/src/app/shared/shared-video-miniature/video-miniature.component.ts b/client/src/app/shared/shared-video-miniature/video-miniature.component.ts index 7de9fc8e2..42c472579 100644 --- a/client/src/app/shared/shared-video-miniature/video-miniature.component.ts +++ b/client/src/app/shared/shared-video-miniature/video-miniature.component.ts @@ -49,7 +49,20 @@ export class VideoMiniatureComponent implements OnInit { state: false, blacklistInfo: false } + @Input() displayVideoActions = true + @Input() videoActionsDisplayOptions: VideoActionsDisplayType = { + playlist: true, + download: false, + update: true, + blacklist: true, + delete: true, + report: true, + duplicate: true, + mute: true, + studio: false, + stats: false + } @Input() actorImageSize: ActorAvatarSize = '40' @@ -62,16 +75,6 @@ export class VideoMiniatureComponent implements OnInit { @Output() videoRemoved = new EventEmitter() @Output() videoAccountMuted = new EventEmitter() - videoActionsDisplayOptions: VideoActionsDisplayType = { - playlist: true, - download: false, - update: true, - blacklist: true, - delete: true, - report: true, - duplicate: true, - mute: true - } showActions = false serverConfig: HTMLServerConfig -- cgit v1.2.3