diff options
author | Chocobozzz <me@florianbigard.com> | 2018-08-06 15:12:54 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-08-08 09:30:31 +0200 |
commit | 43620009d5bc0d2a8da6480276b046d1c946bdc9 (patch) | |
tree | f4bf50816c1bba4fe23682775428f57ae7040fd4 | |
parent | aad0ec24e886a93c5f85cbb8eb4c31ff5e973e1a (diff) | |
download | PeerTube-43620009d5bc0d2a8da6480276b046d1c946bdc9.tar.gz PeerTube-43620009d5bc0d2a8da6480276b046d1c946bdc9.tar.zst PeerTube-43620009d5bc0d2a8da6480276b046d1c946bdc9.zip |
Refractor video upload/import
5 files changed, 107 insertions, 97 deletions
diff --git a/client/src/app/videos/+video-edit/shared/video-send.ts b/client/src/app/videos/+video-edit/shared/video-send.ts new file mode 100644 index 000000000..bc1c7a45b --- /dev/null +++ b/client/src/app/videos/+video-edit/shared/video-send.ts | |||
@@ -0,0 +1,70 @@ | |||
1 | import { FormReactive } from '@app/shared' | ||
2 | import { OnInit } from '@angular/core' | ||
3 | import { CanComponentDeactivate } from '@app/shared/guards/can-deactivate-guard.service' | ||
4 | import { populateAsyncUserVideoChannels } from '@app/shared/misc/utils' | ||
5 | import { VideoConstant, VideoPrivacy } from '../../../../../../shared/models/videos' | ||
6 | import { VideoCaptionEdit } from '@app/shared/video-caption/video-caption-edit.model' | ||
7 | import { LoadingBarService } from '@ngx-loading-bar/core' | ||
8 | import { NotificationsService } from 'angular2-notifications' | ||
9 | import { AuthService, ServerService } from '@app/core' | ||
10 | import { VideoService } from '@app/shared/video/video.service' | ||
11 | import { VideoCaptionService } from '@app/shared/video-caption' | ||
12 | import { catchError, switchMap, tap } from 'rxjs/operators' | ||
13 | import { VideoEdit } from '@app/shared/video/video-edit.model' | ||
14 | |||
15 | export abstract class VideoSend extends FormReactive implements OnInit, CanComponentDeactivate { | ||
16 | |||
17 | userVideoChannels: { id: number, label: string, support: string }[] = [] | ||
18 | videoPrivacies: VideoConstant<string>[] = [] | ||
19 | videoCaptions: VideoCaptionEdit[] = [] | ||
20 | |||
21 | firstStepPrivacyId = 0 | ||
22 | firstStepChannelId = 0 | ||
23 | |||
24 | protected abstract readonly DEFAULT_VIDEO_PRIVACY: VideoPrivacy | ||
25 | |||
26 | protected loadingBar: LoadingBarService | ||
27 | protected notificationsService: NotificationsService | ||
28 | protected authService: AuthService | ||
29 | protected serverService: ServerService | ||
30 | protected videoService: VideoService | ||
31 | protected videoCaptionService: VideoCaptionService | ||
32 | |||
33 | abstract canDeactivate () | ||
34 | |||
35 | ngOnInit () { | ||
36 | this.buildForm({}) | ||
37 | |||
38 | populateAsyncUserVideoChannels(this.authService, this.userVideoChannels) | ||
39 | .then(() => this.firstStepChannelId = this.userVideoChannels[ 0 ].id) | ||
40 | |||
41 | this.serverService.videoPrivaciesLoaded | ||
42 | .subscribe( | ||
43 | () => { | ||
44 | this.videoPrivacies = this.serverService.getVideoPrivacies() | ||
45 | |||
46 | this.firstStepPrivacyId = this.DEFAULT_VIDEO_PRIVACY | ||
47 | }) | ||
48 | } | ||
49 | |||
50 | checkForm () { | ||
51 | this.forceCheck() | ||
52 | |||
53 | return this.form.valid | ||
54 | } | ||
55 | |||
56 | protected updateVideoAndCaptions (video: VideoEdit) { | ||
57 | this.loadingBar.start() | ||
58 | |||
59 | return this.videoService.updateVideo(video) | ||
60 | .pipe( | ||
61 | // Then update captions | ||
62 | switchMap(() => this.videoCaptionService.updateCaptions(video.id, this.videoCaptions)), | ||
63 | tap(() => this.loadingBar.complete()), | ||
64 | catchError(err => { | ||
65 | this.loadingBar.complete() | ||
66 | throw err | ||
67 | }) | ||
68 | ) | ||
69 | } | ||
70 | } | ||
diff --git a/client/src/app/videos/+video-edit/video-add.component.html b/client/src/app/videos/+video-edit/video-add.component.html index 1575007d2..17d086fc6 100644 --- a/client/src/app/videos/+video-edit/video-add.component.html +++ b/client/src/app/videos/+video-edit/video-add.component.html | |||
@@ -6,11 +6,11 @@ | |||
6 | 6 | ||
7 | <tabset class="video-add-tabset root-tabset bootstrap" [ngClass]="{ 'hide-nav': secondStepType !== undefined }"> | 7 | <tabset class="video-add-tabset root-tabset bootstrap" [ngClass]="{ 'hide-nav': secondStepType !== undefined }"> |
8 | 8 | ||
9 | <tab i18n-heading heading="Upload your video"> | 9 | <tab i18n-heading heading="Upload a file"> |
10 | <my-video-upload #videoUpload (firstStepDone)="onFirstStepDone('upload', $event)"></my-video-upload> | 10 | <my-video-upload #videoUpload (firstStepDone)="onFirstStepDone('upload', $event)"></my-video-upload> |
11 | </tab> | 11 | </tab> |
12 | 12 | ||
13 | <tab *ngIf="isVideoImportEnabled()" i18n-heading heading="Import your video"> | 13 | <tab *ngIf="isVideoImportEnabled()" i18n-heading heading="Import with URL"> |
14 | <my-video-import #videoImport (firstStepDone)="onFirstStepDone('import', $event)"></my-video-import> | 14 | <my-video-import #videoImport (firstStepDone)="onFirstStepDone('import', $event)"></my-video-import> |
15 | </tab> | 15 | </tab> |
16 | </tabset> | 16 | </tabset> |
diff --git a/client/src/app/videos/+video-edit/video-add.component.scss b/client/src/app/videos/+video-edit/video-add.component.scss index a811b9cf0..02ee295f9 100644 --- a/client/src/app/videos/+video-edit/video-add.component.scss +++ b/client/src/app/videos/+video-edit/video-add.component.scss | |||
@@ -21,7 +21,10 @@ $background-color: #F7F7F7; | |||
21 | margin-bottom: -$border-width; | 21 | margin-bottom: -$border-width; |
22 | } | 22 | } |
23 | 23 | ||
24 | .nav-link { | 24 | a.nav-link { |
25 | @include disable-default-a-behaviour; | ||
26 | |||
27 | color: #000; | ||
25 | height: 40px !important; | 28 | height: 40px !important; |
26 | padding: 0 30px !important; | 29 | padding: 0 30px !important; |
27 | font-size: 15px; | 30 | font-size: 15px; |
diff --git a/client/src/app/videos/+video-edit/video-import.component.ts b/client/src/app/videos/+video-edit/video-import.component.ts index 5f14efd54..5d355dc8b 100644 --- a/client/src/app/videos/+video-edit/video-import.component.ts +++ b/client/src/app/videos/+video-edit/video-import.component.ts | |||
@@ -2,19 +2,16 @@ import { Component, EventEmitter, OnInit, Output } from '@angular/core' | |||
2 | import { Router } from '@angular/router' | 2 | import { Router } from '@angular/router' |
3 | import { CanComponentDeactivate } from '@app/shared/guards/can-deactivate-guard.service' | 3 | import { CanComponentDeactivate } from '@app/shared/guards/can-deactivate-guard.service' |
4 | import { NotificationsService } from 'angular2-notifications' | 4 | import { NotificationsService } from 'angular2-notifications' |
5 | import { VideoConstant, VideoPrivacy, VideoUpdate } from '../../../../../shared/models/videos' | 5 | import { VideoPrivacy, VideoUpdate } from '../../../../../shared/models/videos' |
6 | import { AuthService, ServerService } from '../../core' | 6 | import { AuthService, ServerService } from '../../core' |
7 | import { FormReactive } from '../../shared' | ||
8 | import { populateAsyncUserVideoChannels } from '../../shared/misc/utils' | ||
9 | import { VideoService } from '../../shared/video/video.service' | 7 | import { VideoService } from '../../shared/video/video.service' |
10 | import { I18n } from '@ngx-translate/i18n-polyfill' | 8 | import { I18n } from '@ngx-translate/i18n-polyfill' |
11 | import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' | 9 | import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' |
12 | import { VideoCaptionEdit } from '@app/shared/video-caption/video-caption-edit.model' | ||
13 | import { VideoImportService } from '@app/shared/video-import' | 10 | import { VideoImportService } from '@app/shared/video-import' |
14 | import { VideoEdit } from '@app/shared/video/video-edit.model' | 11 | import { VideoEdit } from '@app/shared/video/video-edit.model' |
15 | import { switchMap } from 'rxjs/operators' | ||
16 | import { LoadingBarService } from '@ngx-loading-bar/core' | 12 | import { LoadingBarService } from '@ngx-loading-bar/core' |
17 | import { VideoCaptionService } from '@app/shared/video-caption' | 13 | import { VideoCaptionService } from '@app/shared/video-caption' |
14 | import { VideoSend } from '@app/videos/+video-edit/shared/video-send' | ||
18 | 15 | ||
19 | @Component({ | 16 | @Component({ |
20 | selector: 'my-video-import', | 17 | selector: 'my-video-import', |
@@ -24,7 +21,7 @@ import { VideoCaptionService } from '@app/shared/video-caption' | |||
24 | './video-import.component.scss' | 21 | './video-import.component.scss' |
25 | ] | 22 | ] |
26 | }) | 23 | }) |
27 | export class VideoImportComponent extends FormReactive implements OnInit, CanComponentDeactivate { | 24 | export class VideoImportComponent extends VideoSend implements OnInit, CanComponentDeactivate { |
28 | @Output() firstStepDone = new EventEmitter<string>() | 25 | @Output() firstStepDone = new EventEmitter<string>() |
29 | 26 | ||
30 | targetUrl = '' | 27 | targetUrl = '' |
@@ -34,55 +31,33 @@ export class VideoImportComponent extends FormReactive implements OnInit, CanCom | |||
34 | hasImportedVideo = false | 31 | hasImportedVideo = false |
35 | isUpdatingVideo = false | 32 | isUpdatingVideo = false |
36 | 33 | ||
37 | userVideoChannels: { id: number, label: string, support: string }[] = [] | ||
38 | videoPrivacies: VideoConstant<string>[] = [] | ||
39 | videoCaptions: VideoCaptionEdit[] = [] | ||
40 | |||
41 | firstStepPrivacyId = 0 | ||
42 | firstStepChannelId = 0 | ||
43 | video: VideoEdit | 34 | video: VideoEdit |
44 | 35 | ||
36 | protected readonly DEFAULT_VIDEO_PRIVACY = VideoPrivacy.PRIVATE | ||
37 | |||
45 | constructor ( | 38 | constructor ( |
46 | protected formValidatorService: FormValidatorService, | 39 | protected formValidatorService: FormValidatorService, |
40 | protected loadingBar: LoadingBarService, | ||
41 | protected notificationsService: NotificationsService, | ||
42 | protected authService: AuthService, | ||
43 | protected serverService: ServerService, | ||
44 | protected videoService: VideoService, | ||
45 | protected videoCaptionService: VideoCaptionService, | ||
47 | private router: Router, | 46 | private router: Router, |
48 | private loadingBar: LoadingBarService, | ||
49 | private notificationsService: NotificationsService, | ||
50 | private authService: AuthService, | ||
51 | private serverService: ServerService, | ||
52 | private videoService: VideoService, | ||
53 | private videoImportService: VideoImportService, | 47 | private videoImportService: VideoImportService, |
54 | private videoCaptionService: VideoCaptionService, | ||
55 | private i18n: I18n | 48 | private i18n: I18n |
56 | ) { | 49 | ) { |
57 | super() | 50 | super() |
58 | } | 51 | } |
59 | 52 | ||
60 | ngOnInit () { | 53 | ngOnInit () { |
61 | this.buildForm({}) | 54 | super.ngOnInit() |
62 | |||
63 | populateAsyncUserVideoChannels(this.authService, this.userVideoChannels) | ||
64 | .then(() => this.firstStepChannelId = this.userVideoChannels[ 0 ].id) | ||
65 | |||
66 | this.serverService.videoPrivaciesLoaded | ||
67 | .subscribe( | ||
68 | () => { | ||
69 | this.videoPrivacies = this.serverService.getVideoPrivacies() | ||
70 | |||
71 | // Private by default | ||
72 | this.firstStepPrivacyId = VideoPrivacy.PRIVATE | ||
73 | }) | ||
74 | } | 55 | } |
75 | 56 | ||
76 | canDeactivate () { | 57 | canDeactivate () { |
77 | return { canDeactivate: true } | 58 | return { canDeactivate: true } |
78 | } | 59 | } |
79 | 60 | ||
80 | checkForm () { | ||
81 | this.forceCheck() | ||
82 | |||
83 | return this.form.valid | ||
84 | } | ||
85 | |||
86 | isTargetUrlValid () { | 61 | isTargetUrlValid () { |
87 | return this.targetUrl && this.targetUrl.match(/https?:\/\//) | 62 | return this.targetUrl && this.targetUrl.match(/https?:\/\//) |
88 | } | 63 | } |
@@ -130,26 +105,19 @@ export class VideoImportComponent extends FormReactive implements OnInit, CanCom | |||
130 | 105 | ||
131 | this.video.patch(this.form.value) | 106 | this.video.patch(this.form.value) |
132 | 107 | ||
133 | this.loadingBar.start() | ||
134 | this.isUpdatingVideo = true | 108 | this.isUpdatingVideo = true |
135 | 109 | ||
136 | // Update the video | 110 | // Update the video |
137 | this.videoService.updateVideo(this.video) | 111 | this.updateVideoAndCaptions(this.video) |
138 | .pipe( | ||
139 | // Then update captions | ||
140 | switchMap(() => this.videoCaptionService.updateCaptions(this.video.id, this.videoCaptions)) | ||
141 | ) | ||
142 | .subscribe( | 112 | .subscribe( |
143 | () => { | 113 | () => { |
144 | this.isUpdatingVideo = false | 114 | this.isUpdatingVideo = false |
145 | this.loadingBar.complete() | ||
146 | this.notificationsService.success(this.i18n('Success'), this.i18n('Video to import updated.')) | 115 | this.notificationsService.success(this.i18n('Success'), this.i18n('Video to import updated.')) |
147 | 116 | ||
148 | this.router.navigate([ '/my-account', 'video-imports' ]) | 117 | this.router.navigate([ '/my-account', 'video-imports' ]) |
149 | }, | 118 | }, |
150 | 119 | ||
151 | err => { | 120 | err => { |
152 | this.loadingBar.complete() | ||
153 | this.isUpdatingVideo = false | 121 | this.isUpdatingVideo = false |
154 | this.notificationsService.error(this.i18n('Error'), err.message) | 122 | this.notificationsService.error(this.i18n('Error'), err.message) |
155 | console.error(err) | 123 | console.error(err) |
diff --git a/client/src/app/videos/+video-edit/video-upload.component.ts b/client/src/app/videos/+video-edit/video-upload.component.ts index c5e9c1592..983af60ce 100644 --- a/client/src/app/videos/+video-edit/video-upload.component.ts +++ b/client/src/app/videos/+video-edit/video-upload.component.ts | |||
@@ -7,17 +7,14 @@ import { LoadingBarService } from '@ngx-loading-bar/core' | |||
7 | import { NotificationsService } from 'angular2-notifications' | 7 | import { NotificationsService } from 'angular2-notifications' |
8 | import { BytesPipe } from 'ngx-pipes' | 8 | import { BytesPipe } from 'ngx-pipes' |
9 | import { Subscription } from 'rxjs' | 9 | import { Subscription } from 'rxjs' |
10 | import { VideoConstant, VideoPrivacy } from '../../../../../shared/models/videos' | 10 | import { VideoPrivacy } from '../../../../../shared/models/videos' |
11 | import { AuthService, ServerService } from '../../core' | 11 | import { AuthService, ServerService } from '../../core' |
12 | import { FormReactive } from '../../shared' | ||
13 | import { populateAsyncUserVideoChannels } from '../../shared/misc/utils' | ||
14 | import { VideoEdit } from '../../shared/video/video-edit.model' | 12 | import { VideoEdit } from '../../shared/video/video-edit.model' |
15 | import { VideoService } from '../../shared/video/video.service' | 13 | import { VideoService } from '../../shared/video/video.service' |
16 | import { I18n } from '@ngx-translate/i18n-polyfill' | 14 | import { I18n } from '@ngx-translate/i18n-polyfill' |
17 | import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' | 15 | import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' |
18 | import { switchMap } from 'rxjs/operators' | ||
19 | import { VideoCaptionService } from '@app/shared/video-caption' | 16 | import { VideoCaptionService } from '@app/shared/video-caption' |
20 | import { VideoCaptionEdit } from '@app/shared/video-caption/video-caption-edit.model' | 17 | import { VideoSend } from '@app/videos/+video-edit/shared/video-send' |
21 | 18 | ||
22 | @Component({ | 19 | @Component({ |
23 | selector: 'my-video-upload', | 20 | selector: 'my-video-upload', |
@@ -27,13 +24,15 @@ import { VideoCaptionEdit } from '@app/shared/video-caption/video-caption-edit.m | |||
27 | './video-upload.component.scss' | 24 | './video-upload.component.scss' |
28 | ] | 25 | ] |
29 | }) | 26 | }) |
30 | export class VideoUploadComponent extends FormReactive implements OnInit, OnDestroy, CanComponentDeactivate { | 27 | export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy, CanComponentDeactivate { |
31 | @Output() firstStepDone = new EventEmitter<string>() | 28 | @Output() firstStepDone = new EventEmitter<string>() |
32 | @ViewChild('videofileInput') videofileInput | 29 | @ViewChild('videofileInput') videofileInput |
33 | 30 | ||
34 | // So that it can be accessed in the template | 31 | // So that it can be accessed in the template |
35 | readonly SPECIAL_SCHEDULED_PRIVACY = VideoEdit.SPECIAL_SCHEDULED_PRIVACY | 32 | readonly SPECIAL_SCHEDULED_PRIVACY = VideoEdit.SPECIAL_SCHEDULED_PRIVACY |
36 | 33 | ||
34 | userVideoQuotaUsed = 0 | ||
35 | |||
37 | isUploadingVideo = false | 36 | isUploadingVideo = false |
38 | isUpdatingVideo = false | 37 | isUpdatingVideo = false |
39 | videoUploaded = false | 38 | videoUploaded = false |
@@ -44,24 +43,19 @@ export class VideoUploadComponent extends FormReactive implements OnInit, OnDest | |||
44 | uuid: '' | 43 | uuid: '' |
45 | } | 44 | } |
46 | 45 | ||
47 | userVideoChannels: { id: number, label: string, support: string }[] = [] | 46 | protected readonly DEFAULT_VIDEO_PRIVACY = VideoPrivacy.PUBLIC |
48 | userVideoQuotaUsed = 0 | ||
49 | videoPrivacies: VideoConstant<string>[] = [] | ||
50 | firstStepPrivacyId = 0 | ||
51 | firstStepChannelId = 0 | ||
52 | videoCaptions: VideoCaptionEdit[] = [] | ||
53 | 47 | ||
54 | constructor ( | 48 | constructor ( |
55 | protected formValidatorService: FormValidatorService, | 49 | protected formValidatorService: FormValidatorService, |
56 | private router: Router, | 50 | protected loadingBar: LoadingBarService, |
57 | private notificationsService: NotificationsService, | 51 | protected notificationsService: NotificationsService, |
58 | private authService: AuthService, | 52 | protected authService: AuthService, |
53 | protected serverService: ServerService, | ||
54 | protected videoService: VideoService, | ||
55 | protected videoCaptionService: VideoCaptionService, | ||
59 | private userService: UserService, | 56 | private userService: UserService, |
60 | private serverService: ServerService, | 57 | private router: Router, |
61 | private videoService: VideoService, | 58 | private i18n: I18n |
62 | private loadingBar: LoadingBarService, | ||
63 | private i18n: I18n, | ||
64 | private videoCaptionService: VideoCaptionService | ||
65 | ) { | 59 | ) { |
66 | super() | 60 | super() |
67 | } | 61 | } |
@@ -71,28 +65,14 @@ export class VideoUploadComponent extends FormReactive implements OnInit, OnDest | |||
71 | } | 65 | } |
72 | 66 | ||
73 | ngOnInit () { | 67 | ngOnInit () { |
74 | this.buildForm({}) | 68 | super.ngOnInit() |
75 | |||
76 | populateAsyncUserVideoChannels(this.authService, this.userVideoChannels) | ||
77 | .then(() => this.firstStepChannelId = this.userVideoChannels[0].id) | ||
78 | 69 | ||
79 | this.userService.getMyVideoQuotaUsed() | 70 | this.userService.getMyVideoQuotaUsed() |
80 | .subscribe(data => this.userVideoQuotaUsed = data.videoQuotaUsed) | 71 | .subscribe(data => this.userVideoQuotaUsed = data.videoQuotaUsed) |
81 | |||
82 | this.serverService.videoPrivaciesLoaded | ||
83 | .subscribe( | ||
84 | () => { | ||
85 | this.videoPrivacies = this.serverService.getVideoPrivacies() | ||
86 | |||
87 | // Public by default | ||
88 | this.firstStepPrivacyId = VideoPrivacy.PUBLIC | ||
89 | }) | ||
90 | } | 72 | } |
91 | 73 | ||
92 | ngOnDestroy () { | 74 | ngOnDestroy () { |
93 | if (this.videoUploadObservable) { | 75 | if (this.videoUploadObservable) this.videoUploadObservable.unsubscribe() |
94 | this.videoUploadObservable.unsubscribe() | ||
95 | } | ||
96 | } | 76 | } |
97 | 77 | ||
98 | canDeactivate () { | 78 | canDeactivate () { |
@@ -116,12 +96,6 @@ export class VideoUploadComponent extends FormReactive implements OnInit, OnDest | |||
116 | this.uploadFirstStep() | 96 | this.uploadFirstStep() |
117 | } | 97 | } |
118 | 98 | ||
119 | checkForm () { | ||
120 | this.forceCheck() | ||
121 | |||
122 | return this.form.valid | ||
123 | } | ||
124 | |||
125 | cancelUpload () { | 99 | cancelUpload () { |
126 | if (this.videoUploadObservable !== null) { | 100 | if (this.videoUploadObservable !== null) { |
127 | this.videoUploadObservable.unsubscribe() | 101 | this.videoUploadObservable.unsubscribe() |
@@ -225,17 +199,12 @@ export class VideoUploadComponent extends FormReactive implements OnInit, OnDest | |||
225 | video.uuid = this.videoUploadedIds.uuid | 199 | video.uuid = this.videoUploadedIds.uuid |
226 | 200 | ||
227 | this.isUpdatingVideo = true | 201 | this.isUpdatingVideo = true |
228 | this.loadingBar.start() | 202 | |
229 | this.videoService.updateVideo(video) | 203 | this.updateVideoAndCaptions(video) |
230 | .pipe( | ||
231 | // Then update captions | ||
232 | switchMap(() => this.videoCaptionService.updateCaptions(video.id, this.videoCaptions)) | ||
233 | ) | ||
234 | .subscribe( | 204 | .subscribe( |
235 | () => { | 205 | () => { |
236 | this.isUpdatingVideo = false | 206 | this.isUpdatingVideo = false |
237 | this.isUploadingVideo = false | 207 | this.isUploadingVideo = false |
238 | this.loadingBar.complete() | ||
239 | 208 | ||
240 | this.notificationsService.success(this.i18n('Success'), this.i18n('Video published.')) | 209 | this.notificationsService.success(this.i18n('Success'), this.i18n('Video published.')) |
241 | this.router.navigate([ '/videos/watch', video.uuid ]) | 210 | this.router.navigate([ '/videos/watch', video.uuid ]) |