diff --git a/client/src/app/shared/misc/utils.ts b/client/src/app/shared/misc/utils.ts index 78be2e5dd..78e8e9682 100644 --- a/client/src/app/shared/misc/utils.ts +++ b/client/src/app/shared/misc/utils.ts @@ -124,6 +124,10 @@ function sortBy (obj: any[], key1: string, key2?: string) { }) } +function scrollToTop () { + window.scroll(0, 0) +} + export { sortBy, durationToString, @@ -135,5 +139,6 @@ export { immutableAssign, objectToFormData, lineFeedToHtml, - removeElementFromArray + removeElementFromArray, + scrollToTop } diff --git a/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.html b/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.html index a933a64f0..11a81ad66 100644 --- a/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.html +++ b/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.html @@ -45,7 +45,12 @@ -
+
+
Sorry, but something went wrong
+ {{ error }} +
+ +
Congratulations, the video will be imported with BitTorrent! You can already add information about this video.
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.scss b/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.scss index 262b0b68e..00626cd7b 100644 --- a/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.scss +++ b/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.scss @@ -7,6 +7,14 @@ $width-size: 190px; @include peertube-select-container($width-size); } +.alert.alert-danger { + text-align: center; + + & > div { + font-weight: $font-semibold; + } +} + .import-video-torrent { display: flex; flex-direction: column; diff --git a/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.ts b/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.ts index e13c06ce9..13776ae36 100644 --- a/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.ts +++ b/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.ts @@ -12,6 +12,7 @@ import { VideoEdit } from '@app/shared/video/video-edit.model' import { FormValidatorService } from '@app/shared' import { VideoCaptionService } from '@app/shared/video-caption' import { VideoImportService } from '@app/shared/video-import' +import { scrollToTop } from '@app/shared/misc/utils' @Component({ selector: 'my-video-import-torrent', @@ -23,9 +24,9 @@ import { VideoImportService } from '@app/shared/video-import' }) export class VideoImportTorrentComponent extends VideoSend implements OnInit, CanComponentDeactivate { @Output() firstStepDone = new EventEmitter() + @Output() firstStepError = new EventEmitter() @ViewChild('torrentfileInput') torrentfileInput: ElementRef - videoFileName: string magnetUri = '' isImportingVideo = false @@ -33,6 +34,7 @@ export class VideoImportTorrentComponent extends VideoSend implements OnInit, Ca isUpdatingVideo = false video: VideoEdit + error: string protected readonly DEFAULT_VIDEO_PRIVACY = VideoPrivacy.PUBLIC @@ -104,6 +106,7 @@ export class VideoImportTorrentComponent extends VideoSend implements OnInit, Ca err => { this.loadingBar.complete() this.isImportingVideo = false + this.firstStepError.emit() this.notificationsService.error(this.i18n('Error'), err.message) } ) @@ -129,8 +132,8 @@ export class VideoImportTorrentComponent extends VideoSend implements OnInit, Ca }, err => { - this.isUpdatingVideo = false - this.notificationsService.error(this.i18n('Error'), err.message) + this.error = err.message + scrollToTop() console.error(err) } ) diff --git a/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.html b/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.html index 9f5fc6d22..533446672 100644 --- a/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.html +++ b/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.html @@ -37,7 +37,13 @@
-
+ +
+
Sorry, but something went wrong
+ {{ error }} +
+ +
Congratulations, the video behind {{ targetUrl }} will be imported! You can already add information about this video.
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.scss b/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.scss index 7c6deda1d..e907edc70 100644 --- a/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.scss +++ b/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.scss @@ -7,6 +7,14 @@ $width-size: 190px; @include peertube-select-container($width-size); } +.alert.alert-danger { + text-align: center; + + & > div { + font-weight: $font-semibold; + } +} + .import-video-url { display: flex; flex-direction: column; diff --git a/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.ts b/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.ts index 031e557ed..9cdface75 100644 --- a/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.ts +++ b/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.ts @@ -12,6 +12,7 @@ import { VideoEdit } from '@app/shared/video/video-edit.model' import { FormValidatorService } from '@app/shared' import { VideoCaptionService } from '@app/shared/video-caption' import { VideoImportService } from '@app/shared/video-import' +import { scrollToTop } from '@app/shared/misc/utils' @Component({ selector: 'my-video-import-url', @@ -23,15 +24,16 @@ import { VideoImportService } from '@app/shared/video-import' }) export class VideoImportUrlComponent extends VideoSend implements OnInit, CanComponentDeactivate { @Output() firstStepDone = new EventEmitter() + @Output() firstStepError = new EventEmitter() targetUrl = '' - videoFileName: string isImportingVideo = false hasImportedVideo = false isUpdatingVideo = false video: VideoEdit + error: string protected readonly DEFAULT_VIDEO_PRIVACY = VideoPrivacy.PUBLIC @@ -96,6 +98,7 @@ export class VideoImportUrlComponent extends VideoSend implements OnInit, CanCom err => { this.loadingBar.complete() this.isImportingVideo = false + this.firstStepError.emit() this.notificationsService.error(this.i18n('Error'), err.message) } ) @@ -121,8 +124,8 @@ export class VideoImportUrlComponent extends VideoSend implements OnInit, CanCom }, err => { - this.isUpdatingVideo = false - this.notificationsService.error(this.i18n('Error'), err.message) + this.error = err.message + scrollToTop() console.error(err) } ) diff --git a/client/src/app/videos/+video-edit/video-add-components/video-send.ts b/client/src/app/videos/+video-edit/video-add-components/video-send.ts index 1bf22e1a9..71d2544d8 100644 --- a/client/src/app/videos/+video-edit/video-add-components/video-send.ts +++ b/client/src/app/videos/+video-edit/video-add-components/video-send.ts @@ -21,6 +21,7 @@ export abstract class VideoSend extends FormReactive implements OnInit { firstStepChannelId = 0 abstract firstStepDone: EventEmitter + abstract firstStepError: EventEmitter protected abstract readonly DEFAULT_VIDEO_PRIVACY: VideoPrivacy protected loadingBar: LoadingBarService diff --git a/client/src/app/videos/+video-edit/video-add-components/video-upload.component.html b/client/src/app/videos/+video-edit/video-add-components/video-upload.component.html index fa57c8cb5..a09f54dfc 100644 --- a/client/src/app/videos/+video-edit/video-add-components/video-upload.component.html +++ b/client/src/app/videos/+video-edit/video-add-components/video-upload.component.html @@ -29,7 +29,7 @@
-
+
+
+
Sorry, but something went wrong
+ {{ error }} +
+
- \ No newline at end of file + diff --git a/client/src/app/videos/+video-edit/video-add-components/video-upload.component.scss b/client/src/app/videos/+video-edit/video-add-components/video-upload.component.scss index dbae5230d..cf1725ef9 100644 --- a/client/src/app/videos/+video-edit/video-add-components/video-upload.component.scss +++ b/client/src/app/videos/+video-edit/video-add-components/video-upload.component.scss @@ -5,6 +5,14 @@ @include peertube-select-container(190px); } +.alert.alert-danger { + text-align: center; + + & > div { + font-weight: $font-semibold; + } +} + .upload-video { display: flex; flex-direction: column; @@ -82,4 +90,4 @@ margin-left: 10px; } -} \ No newline at end of file +} diff --git a/client/src/app/videos/+video-edit/video-add-components/video-upload.component.ts b/client/src/app/videos/+video-edit/video-add-components/video-upload.component.ts index 8e2d0deaf..3fcb71ac3 100644 --- a/client/src/app/videos/+video-edit/video-add-components/video-upload.component.ts +++ b/client/src/app/videos/+video-edit/video-add-components/video-upload.component.ts @@ -14,6 +14,7 @@ import { VideoSend } from '@app/videos/+video-edit/video-add-components/video-se import { CanComponentDeactivate } from '@app/shared/guards/can-deactivate-guard.service' import { FormValidatorService, UserService } from '@app/shared' import { VideoCaptionService } from '@app/shared/video-caption' +import { scrollToTop } from '@app/shared/misc/utils' @Component({ selector: 'my-video-upload', @@ -25,6 +26,7 @@ import { VideoCaptionService } from '@app/shared/video-caption' }) export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy, CanComponentDeactivate { @Output() firstStepDone = new EventEmitter() + @Output() firstStepError = new EventEmitter() @ViewChild('videofileInput') videofileInput: ElementRef // So that it can be accessed in the template @@ -43,6 +45,8 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy uuid: '' } + error: string + protected readonly DEFAULT_VIDEO_PRIVACY = VideoPrivacy.PUBLIC constructor ( @@ -201,6 +205,7 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy this.isUploadingVideo = false this.videoUploadPercents = 0 this.videoUploadObservable = null + this.firstStepError.emit() this.notificationsService.error(this.i18n('Error'), err.message) } ) @@ -235,8 +240,8 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy }, err => { - this.isUpdatingVideo = false - this.notificationsService.error(this.i18n('Error'), err.message) + this.error = err.message + scrollToTop() console.error(err) } ) 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 e14e23aed..72a233b72 100644 --- a/client/src/app/videos/+video-edit/video-add.component.html +++ b/client/src/app/videos/+video-edit/video-add.component.html @@ -6,24 +6,24 @@ - + Upload a file - + Import with URL - + Import with torrent - + diff --git a/client/src/app/videos/+video-edit/video-add.component.ts b/client/src/app/videos/+video-edit/video-add.component.ts index 1a9247dbe..57a9d0ca7 100644 --- a/client/src/app/videos/+video-edit/video-add.component.ts +++ b/client/src/app/videos/+video-edit/video-add.component.ts @@ -27,6 +27,11 @@ export class VideoAddComponent implements CanComponentDeactivate { this.videoName = videoName } + onError () { + this.videoName = undefined + this.secondStepType = undefined + } + canDeactivate () { if (this.secondStepType === 'upload') return this.videoUpload.canDeactivate() if (this.secondStepType === 'import-url') return this.videoImportUrl.canDeactivate() diff --git a/server/middlewares/validators/videos/videos.ts b/server/middlewares/validators/videos/videos.ts index 656d161d8..bf21bca8c 100644 --- a/server/middlewares/validators/videos/videos.ts +++ b/server/middlewares/validators/videos/videos.ts @@ -393,6 +393,8 @@ export { function areErrorsInScheduleUpdate (req: express.Request, res: express.Response) { if (req.body.scheduleUpdate) { if (!req.body.scheduleUpdate.updateAt) { + logger.warn('Invalid parameters: scheduleUpdate.updateAt is mandatory.') + res.status(400) .json({ error: 'Schedule update at is mandatory.' })