aboutsummaryrefslogtreecommitdiffhomepage
path: root/client
diff options
context:
space:
mode:
authorGreen-Star <Green-Star@users.noreply.github.com>2017-04-26 21:22:10 +0200
committerBigard Florian <florian.bigard@gmail.com>2017-04-26 21:22:10 +0200
commit198b205c10dba362b9ae1ef6895b29d7e0dd685f (patch)
tree3be413139784f7445e775cbecccc6091a738360b /client
parent00871a261787ae1ed8446861ba2bd5eea9faca6d (diff)
downloadPeerTube-198b205c10dba362b9ae1ef6895b29d7e0dd685f.tar.gz
PeerTube-198b205c10dba362b9ae1ef6895b29d7e0dd685f.tar.zst
PeerTube-198b205c10dba362b9ae1ef6895b29d7e0dd685f.zip
Add ability for an administrator to remove any video (#61)
* Add ability for an admin to remove every video on the pod. * Server: add BlacklistedVideos relation. * Server: Insert in BlacklistedVideos relation upon deletion of a video. * Server: Modify BlacklistedVideos schema to add Pod id information. * Server: Moving insertion of a blacklisted video from the `afterDestroy` hook into the process of deletion of a video. To avoid inserting a video when it is removed on its origin pod. When a video is removed on its origin pod, the `afterDestroy` hook is fire, but no request is made on the delete('/:videoId') interface. Hence, we insert into `BlacklistedVideos` only on request on delete('/:videoId') (if requirements for insertion are met). * Server: Add removeVideoFromBlacklist hook on deletion of a video. We are going to proceed in another way :). We will add a new route : /:videoId/blacklist to blacklist a video. We do not blacklist a video upon its deletion now (to distinguish a video blacklist from a regular video delete) When we blacklist a video, the video remains in the DB, so we don't have any concern about its update. It just doesn't appear in the video list. When we remove a video, we then have to remove it from the blacklist too. We could also remove a video from the blacklist to 'unremove' it and make it appear again in the video list (will be another feature). * Server: Add handler for new route post(/:videoId/blacklist) * Client: Add isBlacklistable method * Client: Update isRemovableBy method. * Client: Move 'Delete video' feature from the video-list to the video-watch module. * Server: Exclude blacklisted videos from the video list * Server: Use findAll() in BlacklistedVideos.list() method * Server: Fix addVideoToBlacklist function. * Client: Add blacklist feature. * Server: Use JavaScript Standard Style. * Server: In checkUserCanDeleteVideo, move the callback call inside the db callback function * Server: Modify BlacklistVideo relation * Server: Modifiy Videos methods. * Server: Add checkVideoIsBlacklistable method * Server: Rewrite addVideoToBlacklist method * Server: Fix checkVideoIsBlacklistable method * Server: Add return to addVideoToBlacklist method
Diffstat (limited to 'client')
-rw-r--r--client/src/app/videos/shared/video.model.ts8
-rw-r--r--client/src/app/videos/shared/video.service.ts6
-rw-r--r--client/src/app/videos/video-list/video-list.component.ts5
-rw-r--r--client/src/app/videos/video-list/video-miniature.component.html4
-rw-r--r--client/src/app/videos/video-list/video-miniature.component.scss14
-rw-r--r--client/src/app/videos/video-list/video-miniature.component.ts20
-rw-r--r--client/src/app/videos/video-watch/video-watch.component.html12
-rw-r--r--client/src/app/videos/video-watch/video-watch.component.ts47
8 files changed, 71 insertions, 45 deletions
diff --git a/client/src/app/videos/shared/video.model.ts b/client/src/app/videos/shared/video.model.ts
index 404e3bf45..1cfb312b6 100644
--- a/client/src/app/videos/shared/video.model.ts
+++ b/client/src/app/videos/shared/video.model.ts
@@ -85,8 +85,12 @@ export class Video {
85 this.by = Video.createByString(hash.author, hash.podHost); 85 this.by = Video.createByString(hash.author, hash.podHost);
86 } 86 }
87 87
88 isRemovableBy(user: User) { 88 isRemovableBy(user) {
89 return this.isLocal === true && user && this.author === user.username; 89 return user && this.isLocal === true && (this.author === user.username || user.isAdmin() === true);
90 }
91
92 isBlackistableBy(user) {
93 return user && user.isAdmin() === true && this.isLocal === false;
90 } 94 }
91 95
92 isVideoNSFWForUser(user: User) { 96 isVideoNSFWForUser(user: User) {
diff --git a/client/src/app/videos/shared/video.service.ts b/client/src/app/videos/shared/video.service.ts
index ee67bc1ae..a0965e20c 100644
--- a/client/src/app/videos/shared/video.service.ts
+++ b/client/src/app/videos/shared/video.service.ts
@@ -150,6 +150,12 @@ export class VideoService {
150 .catch((res) => this.restExtractor.handleError(res)); 150 .catch((res) => this.restExtractor.handleError(res));
151 } 151 }
152 152
153 blacklistVideo(id: string) {
154 return this.authHttp.post(VideoService.BASE_VIDEO_URL + id + '/blacklist', {})
155 .map(this.restExtractor.extractDataBool)
156 .catch((res) => this.restExtractor.handleError(res));
157 }
158
153 private setVideoRate(id: string, rateType: RateType) { 159 private setVideoRate(id: string, rateType: RateType) {
154 const url = VideoService.BASE_VIDEO_URL + id + '/rate'; 160 const url = VideoService.BASE_VIDEO_URL + id + '/rate';
155 const body = { 161 const body = {
diff --git a/client/src/app/videos/video-list/video-list.component.ts b/client/src/app/videos/video-list/video-list.component.ts
index ede1b51a9..b9f19b4f1 100644
--- a/client/src/app/videos/video-list/video-list.component.ts
+++ b/client/src/app/videos/video-list/video-list.component.ts
@@ -108,11 +108,6 @@ export class VideoListComponent implements OnInit, OnDestroy {
108 this.navigateToNewParams(); 108 this.navigateToNewParams();
109 } 109 }
110 110
111 onRemoved(video: Video) {
112 this.notificationsService.success('Success', `Video ${video.name} deleted.`);
113 this.getVideos();
114 }
115
116 onSort(sort: SortField) { 111 onSort(sort: SortField) {
117 this.sort = sort; 112 this.sort = sort;
118 113
diff --git a/client/src/app/videos/video-list/video-miniature.component.html b/client/src/app/videos/video-list/video-miniature.component.html
index 94b892698..b8b448631 100644
--- a/client/src/app/videos/video-list/video-miniature.component.html
+++ b/client/src/app/videos/video-list/video-miniature.component.html
@@ -10,10 +10,6 @@
10 10
11 <span class="video-miniature-duration">{{ video.duration }}</span> 11 <span class="video-miniature-duration">{{ video.duration }}</span>
12 </a> 12 </a>
13 <span
14 *ngIf="displayRemoveIcon()" (click)="removeVideo(video.id)"
15 class="video-miniature-remove glyphicon glyphicon-remove"
16 ></span>
17 13
18 <div class="video-miniature-informations"> 14 <div class="video-miniature-informations">
19 <span class="video-miniature-name-tags"> 15 <span class="video-miniature-name-tags">
diff --git a/client/src/app/videos/video-list/video-miniature.component.scss b/client/src/app/videos/video-list/video-miniature.component.scss
index b8e90e8c5..f88ced819 100644
--- a/client/src/app/videos/video-list/video-miniature.component.scss
+++ b/client/src/app/videos/video-list/video-miniature.component.scss
@@ -42,20 +42,6 @@
42 } 42 }
43 } 43 }
44 44
45 .video-miniature-remove {
46 display: inline-block;
47 position: absolute;
48 left: 16px;
49 background-color: rgba(0, 0, 0, 0.8);
50 color: rgba(255, 255, 255, 0.8);
51 padding: 2px;
52 cursor: pointer;
53
54 &:hover {
55 color: rgba(255, 255, 255, 0.9);
56 }
57 }
58
59 .video-miniature-informations { 45 .video-miniature-informations {
60 width: 200px; 46 width: 200px;
61 47
diff --git a/client/src/app/videos/video-list/video-miniature.component.ts b/client/src/app/videos/video-list/video-miniature.component.ts
index 888026dde..13deec381 100644
--- a/client/src/app/videos/video-list/video-miniature.component.ts
+++ b/client/src/app/videos/video-list/video-miniature.component.ts
@@ -13,8 +13,6 @@ import { User } from '../../shared';
13}) 13})
14 14
15export class VideoMiniatureComponent { 15export class VideoMiniatureComponent {
16 @Output() removed = new EventEmitter<any>();
17
18 @Input() currentSort: SortField; 16 @Input() currentSort: SortField;
19 @Input() user: User; 17 @Input() user: User;
20 @Input() video: Video; 18 @Input() video: Video;
@@ -28,10 +26,6 @@ export class VideoMiniatureComponent {
28 private videoService: VideoService 26 private videoService: VideoService
29 ) {} 27 ) {}
30 28
31 displayRemoveIcon() {
32 return this.hovering && this.video.isRemovableBy(this.user);
33 }
34
35 getVideoName() { 29 getVideoName() {
36 if (this.isVideoNSFWForThisUser()) 30 if (this.isVideoNSFWForThisUser())
37 return 'NSFW'; 31 return 'NSFW';
@@ -47,20 +41,6 @@ export class VideoMiniatureComponent {
47 this.hovering = true; 41 this.hovering = true;
48 } 42 }
49 43
50 removeVideo(id: string) {
51 this.confirmService.confirm('Do you really want to delete this video?', 'Delete').subscribe(
52 res => {
53 if (res === false) return;
54
55 this.videoService.removeVideo(id).subscribe(
56 status => this.removed.emit(true),
57
58 error => this.notificationsService.error('Error', error.text)
59 );
60 }
61 );
62 }
63
64 isVideoNSFWForThisUser() { 44 isVideoNSFWForThisUser() {
65 return this.video.isVideoNSFWForUser(this.user); 45 return this.video.isVideoNSFWForUser(this.user);
66 } 46 }
diff --git a/client/src/app/videos/video-watch/video-watch.component.html b/client/src/app/videos/video-watch/video-watch.component.html
index 19e9bd9ed..ed26b513e 100644
--- a/client/src/app/videos/video-watch/video-watch.component.html
+++ b/client/src/app/videos/video-watch/video-watch.component.html
@@ -96,6 +96,18 @@
96 <span class="glyphicon glyphicon-alert"></span> Report 96 <span class="glyphicon glyphicon-alert"></span> Report
97 </a> 97 </a>
98 </li> 98 </li>
99
100 <li *ngIf="isVideoRemovable()" role="menuitem">
101 <a class="dropdown-item" title="Delete this video" href="#" (click)="removeVideo($event)">
102 <span class="glyphicon glyphicon-remove"></span> Delete
103 </a>
104 </li>
105
106 <li *ngIf="isVideoBlacklistable()" role="menuitem">
107 <a class="dropdown-item" title="Blacklist this video" href="#" (click)="blacklistVideo($event)">
108 <span class="glyphicon glyphicon-eye-close"></span> Blacklist
109 </a>
110 </li>
99 </ul> 111 </ul>
100 </div> 112 </div>
101 </div> 113 </div>
diff --git a/client/src/app/videos/video-watch/video-watch.component.ts b/client/src/app/videos/video-watch/video-watch.component.ts
index e04626a67..f582df45c 100644
--- a/client/src/app/videos/video-watch/video-watch.component.ts
+++ b/client/src/app/videos/video-watch/video-watch.component.ts
@@ -169,6 +169,45 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
169 ); 169 );
170 } 170 }
171 171
172 removeVideo(event: Event) {
173 event.preventDefault();
174 this.confirmService.confirm('Do you really want to delete this video?', 'Delete').subscribe(
175 res => {
176 if (res === false) return;
177
178 this.videoService.removeVideo(this.video.id)
179 .subscribe(
180 status => {
181 this.notificationsService.success('Success', `Video ${this.video.name} deleted.`)
182 // Go back to the video-list.
183 this.router.navigate(['/videos/list'])
184 },
185
186 error => this.notificationsService.error('Error', error.text)
187 );
188 }
189 );
190 }
191
192 blacklistVideo(event: Event) {
193 event.preventDefault()
194 this.confirmService.confirm('Do you really want to blacklist this video ?', 'Blacklist').subscribe(
195 res => {
196 if (res === false) return;
197
198 this.videoService.blacklistVideo(this.video.id)
199 .subscribe(
200 status => {
201 this.notificationsService.success('Success', `Video ${this.video.name} had been blacklisted.`)
202 this.router.navigate(['/videos/list'])
203 },
204
205 error => this.notificationsService.error('Error', error.text)
206 )
207 }
208 )
209 }
210
172 showReportModal(event: Event) { 211 showReportModal(event: Event) {
173 event.preventDefault(); 212 event.preventDefault();
174 this.videoReportModal.show(); 213 this.videoReportModal.show();
@@ -192,6 +231,14 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
192 this.authService.getUser().username === this.video.author; 231 this.authService.getUser().username === this.video.author;
193 } 232 }
194 233
234 isVideoRemovable() {
235 return this.video.isRemovableBy(this.authService.getUser());
236 }
237
238 isVideoBlacklistable() {
239 return this.video.isBlackistableBy(this.authService.getUser());
240 }
241
195 private checkUserRating() { 242 private checkUserRating() {
196 // Unlogged users do not have ratings 243 // Unlogged users do not have ratings
197 if (this.isUserLoggedIn() === false) return; 244 if (this.isUserLoggedIn() === false) return;