+
+
+
+
+
Cancel
diff --git a/client/src/app/core/confirm/confirm.component.scss b/client/src/app/core/confirm/confirm.component.scss
new file mode 100644
index 000000000..93dd7926b
--- /dev/null
+++ b/client/src/app/core/confirm/confirm.component.scss
@@ -0,0 +1,17 @@
+@import '_variables';
+@import '_mixins';
+
+.button {
+ padding: 0 13px;
+}
+
+input[type=text] {
+ @include peertube-input-text(100%);
+ display: block;
+}
+
+.form-group {
+ margin: 20px 0;
+}
+
+
diff --git a/client/src/app/core/confirm/confirm.component.ts b/client/src/app/core/confirm/confirm.component.ts
index 0515d969a..8f81b7a98 100644
--- a/client/src/app/core/confirm/confirm.component.ts
+++ b/client/src/app/core/confirm/confirm.component.ts
@@ -4,21 +4,20 @@ import { ModalDirective } from 'ngx-bootstrap/modal'
import { ConfirmService } from './confirm.service'
-export interface ConfigChangedEvent {
- columns: { [id: string]: { isDisplayed: boolean } }
- config: { resultsPerPage: number }
-}
-
@Component({
selector: 'my-confirm',
templateUrl: './confirm.component.html',
- styles: [ '.button { padding: 0 13px; }' ]
+ styleUrls: [ './confirm.component.scss' ]
})
export class ConfirmComponent implements OnInit {
@ViewChild('confirmModal') confirmModal: ModalDirective
title = ''
message = ''
+ expectedInputValue = ''
+ inputLabel = ''
+
+ inputValue = ''
constructor (private confirmService: ConfirmService) {
// Empty
@@ -31,10 +30,13 @@ export class ConfirmComponent implements OnInit {
}
this.confirmService.showConfirm.subscribe(
- ({ title, message }) => {
+ ({ title, message, expectedInputValue, inputLabel }) => {
this.title = title
this.message = message
+ this.inputLabel = inputLabel
+ this.expectedInputValue = expectedInputValue
+
this.showModal()
}
)
@@ -52,6 +54,13 @@ export class ConfirmComponent implements OnInit {
this.hideModal()
}
+ isConfirmationDisabled () {
+ // No input validation
+ if (!this.inputLabel || !this.expectedInputValue) return false
+
+ return this.expectedInputValue !== this.inputValue
+ }
+
showModal () {
this.confirmModal.show()
}
diff --git a/client/src/app/core/confirm/confirm.service.ts b/client/src/app/core/confirm/confirm.service.ts
index f12ff1848..f30feb9d0 100644
--- a/client/src/app/core/confirm/confirm.service.ts
+++ b/client/src/app/core/confirm/confirm.service.ts
@@ -1,15 +1,22 @@
import { Injectable } from '@angular/core'
import { Subject } from 'rxjs/Subject'
import 'rxjs/add/operator/first'
+import 'rxjs/add/operator/toPromise'
@Injectable()
export class ConfirmService {
- showConfirm = new Subject<{ title, message }>()
+ showConfirm = new Subject<{ title: string, message: string, inputLabel?: string, expectedInputValue?: string }>()
confirmResponse = new Subject
()
- confirm (message = '', title = '') {
+ confirm (message: string, title = '') {
this.showConfirm.next({ title, message })
- return this.confirmResponse.asObservable().first()
+ return this.confirmResponse.asObservable().first().toPromise()
+ }
+
+ confirmWithInput (message: string, inputLabel: string, expectedInputValue: string, title = '') {
+ this.showConfirm.next({ title, message, inputLabel, expectedInputValue })
+
+ return this.confirmResponse.asObservable().first().toPromise()
}
}
diff --git a/client/src/app/core/core.module.ts b/client/src/app/core/core.module.ts
index eea6f340b..36dbe8b5c 100644
--- a/client/src/app/core/core.module.ts
+++ b/client/src/app/core/core.module.ts
@@ -1,5 +1,6 @@
import { CommonModule } from '@angular/common'
import { NgModule, Optional, SkipSelf } from '@angular/core'
+import { FormsModule } from '@angular/forms'
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
import { RouterModule } from '@angular/router'
import { LoadingBarModule } from '@ngx-loading-bar/core'
@@ -18,6 +19,7 @@ import { ServerService } from './server'
imports: [
CommonModule,
RouterModule,
+ FormsModule,
BrowserAnimationsModule,
ModalModule,
diff --git a/client/src/app/shared/guards/can-deactivate-guard.service.ts b/client/src/app/shared/guards/can-deactivate-guard.service.ts
index 15618f699..c3b5f37f8 100644
--- a/client/src/app/shared/guards/can-deactivate-guard.service.ts
+++ b/client/src/app/shared/guards/can-deactivate-guard.service.ts
@@ -15,7 +15,7 @@ export class CanDeactivateGuard implements CanDeactivate
currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot,
nextState: RouterStateSnapshot
- ): Observable | boolean {
+ ) {
const result = component.canDeactivate()
const text = result.text || 'All unsaved data will be lost, are you sure you want to leave this page?'
diff --git a/client/src/app/videos/+video-watch/comment/video-comments.component.ts b/client/src/app/videos/+video-watch/comment/video-comments.component.ts
index 16f1a0643..711a01ba0 100644
--- a/client/src/app/videos/+video-watch/comment/video-comments.component.ts
+++ b/client/src/app/videos/+video-watch/comment/video-comments.component.ts
@@ -109,38 +109,35 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy {
this.viewReplies(commentTree.comment.id)
}
- onWantedToDelete (commentToDelete: VideoComment) {
+ async onWantedToDelete (commentToDelete: VideoComment) {
let message = 'Do you really want to delete this comment?'
if (commentToDelete.totalReplies !== 0) message += `${commentToDelete.totalReplies} would be deleted too.`
- this.confirmService.confirm(message, 'Delete').subscribe(
- res => {
- if (res === false) return
+ const res = await this.confirmService.confirm(message, 'Delete')
+ if (res === false) return
- this.videoCommentService.deleteVideoComment(commentToDelete.videoId, commentToDelete.id)
- .subscribe(
- () => {
- // Delete the comment in the tree
- if (commentToDelete.inReplyToCommentId) {
- const thread = this.threadComments[commentToDelete.threadId]
- if (!thread) {
- console.error(`Cannot find thread ${commentToDelete.threadId} of the comment to delete ${commentToDelete.id}`)
- return
- }
+ this.videoCommentService.deleteVideoComment(commentToDelete.videoId, commentToDelete.id)
+ .subscribe(
+ () => {
+ // Delete the comment in the tree
+ if (commentToDelete.inReplyToCommentId) {
+ const thread = this.threadComments[commentToDelete.threadId]
+ if (!thread) {
+ console.error(`Cannot find thread ${commentToDelete.threadId} of the comment to delete ${commentToDelete.id}`)
+ return
+ }
- this.deleteLocalCommentThread(thread, commentToDelete)
- return
- }
+ this.deleteLocalCommentThread(thread, commentToDelete)
+ return
+ }
- // Delete the thread
- this.comments = this.comments.filter(c => c.id !== commentToDelete.id)
- this.componentPagination.totalItems--
- },
+ // Delete the thread
+ this.comments = this.comments.filter(c => c.id !== commentToDelete.id)
+ this.componentPagination.totalItems--
+ },
- err => this.notificationsService.error('Error', err.message)
- )
- }
- )
+ err => this.notificationsService.error('Error', err.message)
+ )
}
isUserLoggedIn () {
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 6b118b1de..d04d50310 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/videos/+video-watch/video-watch.component.ts
@@ -130,24 +130,21 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
}
}
- blacklistVideo (event: Event) {
+ async blacklistVideo (event: Event) {
event.preventDefault()
- this.confirmService.confirm('Do you really want to blacklist this video?', 'Blacklist').subscribe(
- res => {
- if (res === false) return
+ const res = await this.confirmService.confirm('Do you really want to blacklist this video?', 'Blacklist')
+ if (res === false) return
- this.videoBlacklistService.blacklistVideo(this.video.id)
- .subscribe(
- status => {
- this.notificationsService.success('Success', `Video ${this.video.name} had been blacklisted.`)
- this.router.navigate(['/videos/list'])
- },
+ this.videoBlacklistService.blacklistVideo(this.video.id)
+ .subscribe(
+ status => {
+ this.notificationsService.success('Success', `Video ${this.video.name} had been blacklisted.`)
+ this.router.navigate(['/videos/list'])
+ },
- error => this.notificationsService.error('Error', error.message)
- )
- }
- )
+ error => this.notificationsService.error('Error', error.message)
+ )
}
showMoreDescription () {
@@ -236,26 +233,22 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
return this.video.isRemovableBy(this.authService.getUser())
}
- removeVideo (event: Event) {
+ async removeVideo (event: Event) {
event.preventDefault()
- this.confirmService.confirm('Do you really want to delete this video?', 'Delete')
+ const res = await this.confirmService.confirm('Do you really want to delete this video?', 'Delete')
+ if (res === false) return
+
+ this.videoService.removeVideo(this.video.id)
.subscribe(
- res => {
- if (res === false) return
+ status => {
+ this.notificationsService.success('Success', `Video ${this.video.name} deleted.`)
- this.videoService.removeVideo(this.video.id)
- .subscribe(
- status => {
- this.notificationsService.success('Success', `Video ${this.video.name} deleted.`)
+ // Go back to the video-list.
+ this.router.navigate([ '/videos/list' ])
+ },
- // Go back to the video-list.
- this.router.navigate([ '/videos/list' ])
- },
-
- error => this.notificationsService.error('Error', error.message)
- )
- }
+ error => this.notificationsService.error('Error', error.message)
)
}
diff --git a/server/controllers/client.ts b/server/controllers/client.ts
index 2fcca6f76..df2eee9c9 100644
--- a/server/controllers/client.ts
+++ b/server/controllers/client.ts
@@ -10,7 +10,7 @@ import { VideoModel } from '../models/video/video'
const clientsRouter = express.Router()
const distPath = join(root(), 'client', 'dist')
-const assetsImagesPath = join(root(), 'client', 'dist', 'client', 'assets', 'images')
+const assetsImagesPath = join(root(), 'client', 'dist', 'assets', 'images')
const embedPath = join(distPath, 'standalone', 'videos', 'embed.html')
const indexPath = join(distPath, 'index.html')