aboutsummaryrefslogtreecommitdiffhomepage
path: root/client
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2020-11-18 15:29:38 +0100
committerChocobozzz <me@florianbigard.com>2020-11-18 15:29:38 +0100
commit0aa52e170727ac6bdf441bcaa2353ae0b8a354ed (patch)
tree52fa047cf9970590cab1dcc7a3e5caa8eb004171 /client
parentff2cac9fa361a3c5489078f441ed54230c045971 (diff)
downloadPeerTube-0aa52e170727ac6bdf441bcaa2353ae0b8a354ed.tar.gz
PeerTube-0aa52e170727ac6bdf441bcaa2353ae0b8a354ed.tar.zst
PeerTube-0aa52e170727ac6bdf441bcaa2353ae0b8a354ed.zip
Add ability to display all channel/account videos
Diffstat (limited to 'client')
-rw-r--r--client/src/app/+accounts/account-video-channels/account-video-channels.component.ts18
-rw-r--r--client/src/app/+accounts/account-videos/account-videos.component.ts20
-rw-r--r--client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts20
-rw-r--r--client/src/app/+videos/video-list/video-local.component.ts8
-rw-r--r--client/src/app/shared/shared-main/video/video.service.ts27
-rw-r--r--client/src/app/shared/shared-video-miniature/abstract-video-list.html2
-rw-r--r--client/src/app/shared/shared-video-miniature/abstract-video-list.scss12
-rw-r--r--client/src/app/shared/shared-video-miniature/abstract-video-list.ts32
-rw-r--r--client/src/sass/bootstrap.scss4
9 files changed, 120 insertions, 23 deletions
diff --git a/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts b/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts
index 205245675..f2beb6689 100644
--- a/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts
+++ b/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts
@@ -3,7 +3,7 @@ import { concatMap, map, switchMap, tap } from 'rxjs/operators'
3import { Component, OnDestroy, OnInit } from '@angular/core' 3import { Component, OnDestroy, OnInit } from '@angular/core'
4import { ComponentPagination, hasMoreItems, ScreenService, User, UserService } from '@app/core' 4import { ComponentPagination, hasMoreItems, ScreenService, User, UserService } from '@app/core'
5import { Account, AccountService, Video, VideoChannel, VideoChannelService, VideoService } from '@app/shared/shared-main' 5import { Account, AccountService, Video, VideoChannel, VideoChannelService, VideoService } from '@app/shared/shared-main'
6import { VideoSortField } from '@shared/models' 6import { NSFWPolicyType, VideoSortField } from '@shared/models'
7 7
8@Component({ 8@Component({
9 selector: 'my-account-video-channels', 9 selector: 'my-account-video-channels',
@@ -31,6 +31,7 @@ export class AccountVideoChannelsComponent implements OnInit, OnDestroy {
31 onChannelDataSubject = new Subject<any>() 31 onChannelDataSubject = new Subject<any>()
32 32
33 userMiniature: User 33 userMiniature: User
34 nsfwPolicy: NSFWPolicyType
34 35
35 private accountSub: Subscription 36 private accountSub: Subscription
36 37
@@ -52,7 +53,11 @@ export class AccountVideoChannelsComponent implements OnInit, OnDestroy {
52 }) 53 })
53 54
54 this.userService.getAnonymousOrLoggedUser() 55 this.userService.getAnonymousOrLoggedUser()
55 .subscribe(user => this.userMiniature = user) 56 .subscribe(user => {
57 this.userMiniature = user
58
59 this.nsfwPolicy = user.nsfwPolicy
60 })
56 } 61 }
57 62
58 ngOnDestroy () { 63 ngOnDestroy () {
@@ -65,7 +70,14 @@ export class AccountVideoChannelsComponent implements OnInit, OnDestroy {
65 tap(res => this.channelPagination.totalItems = res.total), 70 tap(res => this.channelPagination.totalItems = res.total),
66 switchMap(res => from(res.data)), 71 switchMap(res => from(res.data)),
67 concatMap(videoChannel => { 72 concatMap(videoChannel => {
68 return this.videoService.getVideoChannelVideos(videoChannel, this.videosPagination, this.videosSort) 73 const options = {
74 videoChannel,
75 videoPagination: this.videosPagination,
76 sort: this.videosSort,
77 nsfwPolicy: this.nsfwPolicy
78 }
79
80 return this.videoService.getVideoChannelVideos(options)
69 .pipe(map(data => ({ videoChannel, videos: data.data }))) 81 .pipe(map(data => ({ videoChannel, videos: data.data })))
70 }) 82 })
71 ) 83 )
diff --git a/client/src/app/+accounts/account-videos/account-videos.component.ts b/client/src/app/+accounts/account-videos/account-videos.component.ts
index 3134a8ee2..58d0719fd 100644
--- a/client/src/app/+accounts/account-videos/account-videos.component.ts
+++ b/client/src/app/+accounts/account-videos/account-videos.component.ts
@@ -6,6 +6,7 @@ import { AuthService, ConfirmService, LocalStorageService, Notifier, ScreenServi
6import { immutableAssign } from '@app/helpers' 6import { immutableAssign } from '@app/helpers'
7import { Account, AccountService, VideoService } from '@app/shared/shared-main' 7import { Account, AccountService, VideoService } from '@app/shared/shared-main'
8import { AbstractVideoList } from '@app/shared/shared-video-miniature' 8import { AbstractVideoList } from '@app/shared/shared-video-miniature'
9import { VideoFilter } from '@shared/models'
9 10
10@Component({ 11@Component({
11 selector: 'my-account-videos', 12 selector: 'my-account-videos',
@@ -18,6 +19,8 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit,
18 titlePage: string 19 titlePage: string
19 loadOnInit = false 20 loadOnInit = false
20 21
22 filter: VideoFilter = null
23
21 private account: Account 24 private account: Account
22 private accountSub: Subscription 25 private accountSub: Subscription
23 26
@@ -40,6 +43,8 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit,
40 ngOnInit () { 43 ngOnInit () {
41 super.ngOnInit() 44 super.ngOnInit()
42 45
46 this.enableAllFilterIfPossible()
47
43 // Parent get the account for us 48 // Parent get the account for us
44 this.accountSub = this.accountService.accountLoaded 49 this.accountSub = this.accountService.accountLoaded
45 .pipe(first()) 50 .pipe(first())
@@ -59,9 +64,16 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit,
59 64
60 getVideosObservable (page: number) { 65 getVideosObservable (page: number) {
61 const newPagination = immutableAssign(this.pagination, { currentPage: page }) 66 const newPagination = immutableAssign(this.pagination, { currentPage: page })
67 const options = {
68 account: this.account,
69 videoPagination: newPagination,
70 sort: this.sort,
71 nsfwPolicy: this.nsfwPolicy,
72 videoFilter: this.filter
73 }
62 74
63 return this.videoService 75 return this.videoService
64 .getAccountVideos(this.account, newPagination, this.sort) 76 .getAccountVideos(options)
65 .pipe( 77 .pipe(
66 tap(({ total }) => { 78 tap(({ total }) => {
67 this.titlePage = $localize`Published ${total} videos` 79 this.titlePage = $localize`Published ${total} videos`
@@ -69,6 +81,12 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit,
69 ) 81 )
70 } 82 }
71 83
84 toggleModerationDisplay () {
85 this.filter = this.buildLocalFilter(this.filter, null)
86
87 this.reloadVideos()
88 }
89
72 generateSyndicationList () { 90 generateSyndicationList () {
73 this.syndicationItems = this.videoService.getAccountFeedUrls(this.account.id) 91 this.syndicationItems = this.videoService.getAccountFeedUrls(this.account.id)
74 } 92 }
diff --git a/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts
index e1ec6bbcb..645696f48 100644
--- a/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts
+++ b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts
@@ -6,6 +6,7 @@ import { AuthService, ConfirmService, LocalStorageService, Notifier, ScreenServi
6import { immutableAssign } from '@app/helpers' 6import { immutableAssign } from '@app/helpers'
7import { VideoChannel, VideoChannelService, VideoService } from '@app/shared/shared-main' 7import { VideoChannel, VideoChannelService, VideoService } from '@app/shared/shared-main'
8import { AbstractVideoList } from '@app/shared/shared-video-miniature' 8import { AbstractVideoList } from '@app/shared/shared-video-miniature'
9import { VideoFilter } from '@shared/models'
9 10
10@Component({ 11@Component({
11 selector: 'my-video-channel-videos', 12 selector: 'my-video-channel-videos',
@@ -18,6 +19,8 @@ export class VideoChannelVideosComponent extends AbstractVideoList implements On
18 titlePage: string 19 titlePage: string
19 loadOnInit = false 20 loadOnInit = false
20 21
22 filter: VideoFilter = null
23
21 private videoChannel: VideoChannel 24 private videoChannel: VideoChannel
22 private videoChannelSub: Subscription 25 private videoChannelSub: Subscription
23 26
@@ -46,6 +49,8 @@ export class VideoChannelVideosComponent extends AbstractVideoList implements On
46 ngOnInit () { 49 ngOnInit () {
47 super.ngOnInit() 50 super.ngOnInit()
48 51
52 this.enableAllFilterIfPossible()
53
49 // Parent get the video channel for us 54 // Parent get the video channel for us
50 this.videoChannelSub = this.videoChannelService.videoChannelLoaded 55 this.videoChannelSub = this.videoChannelService.videoChannelLoaded
51 .pipe(first()) 56 .pipe(first())
@@ -65,9 +70,16 @@ export class VideoChannelVideosComponent extends AbstractVideoList implements On
65 70
66 getVideosObservable (page: number) { 71 getVideosObservable (page: number) {
67 const newPagination = immutableAssign(this.pagination, { currentPage: page }) 72 const newPagination = immutableAssign(this.pagination, { currentPage: page })
73 const options = {
74 videoChannel: this.videoChannel,
75 videoPagination: newPagination,
76 sort: this.sort,
77 nsfwPolicy: this.nsfwPolicy,
78 videoFilter: this.filter
79 }
68 80
69 return this.videoService 81 return this.videoService
70 .getVideoChannelVideos(this.videoChannel, newPagination, this.sort, this.nsfwPolicy) 82 .getVideoChannelVideos(options)
71 .pipe( 83 .pipe(
72 tap(({ total }) => { 84 tap(({ total }) => {
73 this.titlePage = total === 1 85 this.titlePage = total === 1
@@ -80,4 +92,10 @@ export class VideoChannelVideosComponent extends AbstractVideoList implements On
80 generateSyndicationList () { 92 generateSyndicationList () {
81 this.syndicationItems = this.videoService.getVideoChannelFeedUrls(this.videoChannel.id) 93 this.syndicationItems = this.videoService.getVideoChannelFeedUrls(this.videoChannel.id)
82 } 94 }
95
96 toggleModerationDisplay () {
97 this.filter = this.buildLocalFilter(this.filter, null)
98
99 this.reloadVideos()
100 }
83} 101}
diff --git a/client/src/app/+videos/video-list/video-local.component.ts b/client/src/app/+videos/video-list/video-local.component.ts
index 07063d4d4..20dd61db9 100644
--- a/client/src/app/+videos/video-list/video-local.component.ts
+++ b/client/src/app/+videos/video-list/video-local.component.ts
@@ -39,11 +39,7 @@ export class VideoLocalComponent extends AbstractVideoList implements OnInit, On
39 ngOnInit () { 39 ngOnInit () {
40 super.ngOnInit() 40 super.ngOnInit()
41 41
42 if (this.authService.isLoggedIn()) { 42 this.enableAllFilterIfPossible()
43 const user = this.authService.getUser()
44 this.displayModerationBlock = user.hasRight(UserRight.SEE_ALL_VIDEOS)
45 }
46
47 this.generateSyndicationList() 43 this.generateSyndicationList()
48 } 44 }
49 45
@@ -77,7 +73,7 @@ export class VideoLocalComponent extends AbstractVideoList implements OnInit, On
77 } 73 }
78 74
79 toggleModerationDisplay () { 75 toggleModerationDisplay () {
80 this.filter = this.filter === 'local' ? 'all-local' as 'all-local' : 'local' as 'local' 76 this.filter = this.buildLocalFilter(this.filter, 'local')
81 77
82 this.reloadVideos() 78 this.reloadVideos()
83 } 79 }
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 0e2d36081..c8a3ec043 100644
--- a/client/src/app/shared/shared-main/video/video.service.ts
+++ b/client/src/app/shared/shared-main/video/video.service.ts
@@ -134,16 +134,28 @@ export class VideoService implements VideosProvider {
134 ) 134 )
135 } 135 }
136 136
137 getAccountVideos ( 137 getAccountVideos (parameters: {
138 account: Account, 138 account: Account,
139 videoPagination: ComponentPaginationLight, 139 videoPagination: ComponentPaginationLight,
140 sort: VideoSortField 140 sort: VideoSortField
141 ): Observable<ResultList<Video>> { 141 nsfwPolicy?: NSFWPolicyType
142 videoFilter?: VideoFilter
143 }): Observable<ResultList<Video>> {
144 const { account, videoPagination, sort, videoFilter, nsfwPolicy } = parameters
145
142 const pagination = this.restService.componentPaginationToRestPagination(videoPagination) 146 const pagination = this.restService.componentPaginationToRestPagination(videoPagination)
143 147
144 let params = new HttpParams() 148 let params = new HttpParams()
145 params = this.restService.addRestGetParams(params, pagination, sort) 149 params = this.restService.addRestGetParams(params, pagination, sort)
146 150
151 if (nsfwPolicy) {
152 params = params.set('nsfw', this.nsfwPolicyToParam(nsfwPolicy))
153 }
154
155 if (videoFilter) {
156 params = params.set('filter', videoFilter)
157 }
158
147 return this.authHttp 159 return this.authHttp
148 .get<ResultList<Video>>(AccountService.BASE_ACCOUNT_URL + account.nameWithHost + '/videos', { params }) 160 .get<ResultList<Video>>(AccountService.BASE_ACCOUNT_URL + account.nameWithHost + '/videos', { params })
149 .pipe( 161 .pipe(
@@ -152,12 +164,15 @@ export class VideoService implements VideosProvider {
152 ) 164 )
153 } 165 }
154 166
155 getVideoChannelVideos ( 167 getVideoChannelVideos (parameters: {
156 videoChannel: VideoChannel, 168 videoChannel: VideoChannel,
157 videoPagination: ComponentPaginationLight, 169 videoPagination: ComponentPaginationLight,
158 sort: VideoSortField, 170 sort: VideoSortField,
159 nsfwPolicy?: NSFWPolicyType 171 nsfwPolicy?: NSFWPolicyType
160 ): Observable<ResultList<Video>> { 172 videoFilter?: VideoFilter
173 }): Observable<ResultList<Video>> {
174 const { videoChannel, videoPagination, sort, nsfwPolicy, videoFilter } = parameters
175
161 const pagination = this.restService.componentPaginationToRestPagination(videoPagination) 176 const pagination = this.restService.componentPaginationToRestPagination(videoPagination)
162 177
163 let params = new HttpParams() 178 let params = new HttpParams()
@@ -167,6 +182,10 @@ export class VideoService implements VideosProvider {
167 params = params.set('nsfw', this.nsfwPolicyToParam(nsfwPolicy)) 182 params = params.set('nsfw', this.nsfwPolicyToParam(nsfwPolicy))
168 } 183 }
169 184
185 if (videoFilter) {
186 params = params.set('filter', videoFilter)
187 }
188
170 return this.authHttp 189 return this.authHttp
171 .get<ResultList<Video>>(VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannel.nameWithHost + '/videos', { params }) 190 .get<ResultList<Video>>(VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannel.nameWithHost + '/videos', { params })
172 .pipe( 191 .pipe(
diff --git a/client/src/app/shared/shared-video-miniature/abstract-video-list.html b/client/src/app/shared/shared-video-miniature/abstract-video-list.html
index 08962dff8..b1ac757db 100644
--- a/client/src/app/shared/shared-video-miniature/abstract-video-list.html
+++ b/client/src/app/shared/shared-video-miniature/abstract-video-list.html
@@ -21,7 +21,7 @@
21 <div class="dropdown-item"> 21 <div class="dropdown-item">
22 <my-peertube-checkbox 22 <my-peertube-checkbox
23 (change)="toggleModerationDisplay()" 23 (change)="toggleModerationDisplay()"
24 inputName="display-unlisted-private" i18n-labelText labelText="Display unlisted and private videos" 24 inputName="display-unlisted-private" i18n-labelText labelText="Display all videos (private, unlisted or not yet published)"
25 ></my-peertube-checkbox> 25 ></my-peertube-checkbox>
26 </div> 26 </div>
27 </div> 27 </div>
diff --git a/client/src/app/shared/shared-video-miniature/abstract-video-list.scss b/client/src/app/shared/shared-video-miniature/abstract-video-list.scss
index 7841b60f7..9077e2f75 100644
--- a/client/src/app/shared/shared-video-miniature/abstract-video-list.scss
+++ b/client/src/app/shared/shared-video-miniature/abstract-video-list.scss
@@ -31,13 +31,21 @@ $iconSize: 16px;
31 31
32 .moderation-block { 32 .moderation-block {
33 div { 33 div {
34 @include button-with-icon($iconSize, 3px, -1px); 34 @include button-with-icon($iconSize, 3px, -2px);
35 } 35 }
36 36
37 margin-left: .2rem; 37 margin-left: .4rem;
38 display: flex; 38 display: flex;
39 justify-content: flex-end; 39 justify-content: flex-end;
40 align-items: center; 40 align-items: center;
41
42 .dropdown-item {
43 padding: 0;
44
45 ::ng-deep my-peertube-checkbox label {
46 padding: 3px 15px;
47 }
48 }
41 } 49 }
42} 50}
43 51
diff --git a/client/src/app/shared/shared-video-miniature/abstract-video-list.ts b/client/src/app/shared/shared-video-miniature/abstract-video-list.ts
index da05e15fb..2219ced30 100644
--- a/client/src/app/shared/shared-video-miniature/abstract-video-list.ts
+++ b/client/src/app/shared/shared-video-miniature/abstract-video-list.ts
@@ -15,7 +15,7 @@ import {
15import { DisableForReuseHook } from '@app/core/routing/disable-for-reuse-hook' 15import { DisableForReuseHook } from '@app/core/routing/disable-for-reuse-hook'
16import { GlobalIconName } from '@app/shared/shared-icons' 16import { GlobalIconName } from '@app/shared/shared-icons'
17import { isLastMonth, isLastWeek, isThisMonth, isToday, isYesterday } from '@shared/core-utils/miscs/date' 17import { isLastMonth, isLastWeek, isThisMonth, isToday, isYesterday } from '@shared/core-utils/miscs/date'
18import { ServerConfig, VideoSortField } from '@shared/models' 18import { ServerConfig, UserRight, VideoFilter, VideoSortField } from '@shared/models'
19import { NSFWPolicyType } from '@shared/models/videos/nsfw-policy.type' 19import { NSFWPolicyType } from '@shared/models/videos/nsfw-policy.type'
20import { Syndication, Video } from '../shared-main' 20import { Syndication, Video } from '../shared-main'
21import { MiniatureDisplayOptions, OwnerDisplayType } from './video-miniature.component' 21import { MiniatureDisplayOptions, OwnerDisplayType } from './video-miniature.component'
@@ -205,10 +205,6 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor
205 this.loadMoreVideos(true) 205 this.loadMoreVideos(true)
206 } 206 }
207 207
208 toggleModerationDisplay () {
209 throw new Error('toggleModerationDisplay is not implemented')
210 }
211
212 removeVideoFromArray (video: Video) { 208 removeVideoFromArray (video: Video) {
213 this.videos = this.videos.filter(v => v.id !== video.id) 209 this.videos = this.videos.filter(v => v.id !== video.id)
214 } 210 }
@@ -268,6 +264,10 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor
268 return this.groupedDateLabels[this.groupedDates[video.id]] 264 return this.groupedDateLabels[this.groupedDates[video.id]]
269 } 265 }
270 266
267 toggleModerationDisplay () {
268 throw new Error('toggleModerationDisplay is not implemented')
269 }
270
271 // On videos hook for children that want to do something 271 // On videos hook for children that want to do something
272 protected onMoreVideos () { /* empty */ } 272 protected onMoreVideos () { /* empty */ }
273 273
@@ -277,6 +277,28 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor
277 this.angularState = routeParams[ 'a-state' ] 277 this.angularState = routeParams[ 'a-state' ]
278 } 278 }
279 279
280 protected buildLocalFilter (existing: VideoFilter, base: VideoFilter) {
281 if (base === 'local') {
282 return existing === 'local'
283 ? 'all-local' as 'all-local'
284 : 'local' as 'local'
285 }
286
287 return existing === 'all'
288 ? null
289 : 'all'
290 }
291
292 protected enableAllFilterIfPossible () {
293 if (!this.authService.isLoggedIn()) return
294
295 this.authService.userInformationLoaded
296 .subscribe(() => {
297 const user = this.authService.getUser()
298 this.displayModerationBlock = user.hasRight(UserRight.SEE_ALL_VIDEOS)
299 })
300 }
301
280 private calcPageSizes () { 302 private calcPageSizes () {
281 if (this.screenService.isInMobileView()) { 303 if (this.screenService.isInMobileView()) {
282 this.pagination.itemsPerPage = 5 304 this.pagination.itemsPerPage = 5
diff --git a/client/src/sass/bootstrap.scss b/client/src/sass/bootstrap.scss
index 259af7a77..7cb149f5f 100644
--- a/client/src/sass/bootstrap.scss
+++ b/client/src/sass/bootstrap.scss
@@ -65,6 +65,10 @@ $icon-font-path: '~@neos21/bootstrap3-glyphicons/assets/fonts/';
65 opacity: .9; 65 opacity: .9;
66 } 66 }
67 67
68 &:active {
69 color: pvar(--mainForegroundColor) !important;
70 }
71
68 &::after { 72 &::after {
69 display: none; 73 display: none;
70 } 74 }