Improve video upload error handling

pull/1345/head
Chocobozzz 2018-11-16 10:05:25 +01:00
parent fe05c3acbd
commit 7373507fa8
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
14 changed files with 82 additions and 18 deletions

View File

@ -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
}

View File

@ -45,7 +45,12 @@
</div>
</div>
<div *ngIf="hasImportedVideo" class="alert alert-info" i18n>
<div *ngIf="error" class="alert alert-danger">
<div i18n>Sorry, but something went wrong</div>
{{ error }}
</div>
<div *ngIf="hasImportedVideo && !error" class="alert alert-info" i18n>
Congratulations, the video will be imported with BitTorrent! You can already add information about this video.
</div>

View File

@ -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;

View File

@ -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<string>()
@Output() firstStepError = new EventEmitter<void>()
@ViewChild('torrentfileInput') torrentfileInput: ElementRef<HTMLInputElement>
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)
}
)

View File

@ -37,7 +37,13 @@
</div>
</div>
<div *ngIf="hasImportedVideo" class="alert alert-info" i18n>
<div *ngIf="error" class="alert alert-danger">
<div i18n>Sorry, but something went wrong</div>
{{ error }}
</div>
<div *ngIf="!error && hasImportedVideo" class="alert alert-info" i18n>
Congratulations, the video behind {{ targetUrl }} will be imported! You can already add information about this video.
</div>

View File

@ -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;

View File

@ -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<string>()
@Output() firstStepError = new EventEmitter<void>()
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)
}
)

View File

@ -21,6 +21,7 @@ export abstract class VideoSend extends FormReactive implements OnInit {
firstStepChannelId = 0
abstract firstStepDone: EventEmitter<string>
abstract firstStepError: EventEmitter<void>
protected abstract readonly DEFAULT_VIDEO_PRIVACY: VideoPrivacy
protected loadingBar: LoadingBarService

View File

@ -29,7 +29,7 @@
</div>
</div>
<div *ngIf="isUploadingVideo" class="upload-progress-cancel">
<div *ngIf="isUploadingVideo && !error" class="upload-progress-cancel">
<p-progressBar
[value]="videoUploadPercents"
[ngClass]="{ processing: videoUploadPercents === 100 && videoUploaded === false }"
@ -37,6 +37,11 @@
<input *ngIf="videoUploaded === false" type="button" value="Cancel" (click)="cancelUpload()" />
</div>
<div *ngIf="error" class="alert alert-danger">
<div i18n>Sorry, but something went wrong</div>
{{ error }}
</div>
<!-- Hidden because we want to load the component -->
<form [hidden]="!isUploadingVideo" novalidate [formGroup]="form">
<my-video-edit
@ -55,4 +60,4 @@
<input [disabled]="isPublishingButtonDisabled()" type="button" i18n-value value="Publish" />
</div>
</div>
</form>
</form>

View File

@ -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;
}
}
}

View File

@ -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<string>()
@Output() firstStepError = new EventEmitter<void>()
@ViewChild('videofileInput') videofileInput: ElementRef<HTMLInputElement>
// 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)
}
)

View File

@ -6,24 +6,24 @@
<ngb-tabset class="video-add-tabset root-tabset bootstrap" [ngClass]="{ 'hide-nav': secondStepType !== undefined }">
<ngb-tab i18n-title title="">
<ngb-tab>
<ng-template ngbTabTitle><span i18n>Upload a file</span></ng-template>
<ng-template ngbTabContent>
<my-video-upload #videoUpload (firstStepDone)="onFirstStepDone('upload', $event)"></my-video-upload>
<my-video-upload #videoUpload (firstStepDone)="onFirstStepDone('upload', $event)" (firstStepError)="onError()"></my-video-upload>
</ng-template>
</ngb-tab>
<ngb-tab *ngIf="isVideoImportHttpEnabled()">
<ng-template ngbTabTitle><span i18n>Import with URL</span></ng-template>
<ng-template ngbTabContent>
<my-video-import-url #videoImportUrl (firstStepDone)="onFirstStepDone('import-url', $event)"></my-video-import-url>
<my-video-import-url #videoImportUrl (firstStepDone)="onFirstStepDone('import-url', $event)" (firstStepError)="onError()"></my-video-import-url>
</ng-template>
</ngb-tab>
<ngb-tab *ngIf="isVideoImportTorrentEnabled()">
<ng-template ngbTabTitle><span i18n>Import with torrent</span></ng-template>
<ng-template ngbTabContent>
<my-video-import-torrent #videoImportTorrent (firstStepDone)="onFirstStepDone('import-torrent', $event)"></my-video-import-torrent>
<my-video-import-torrent #videoImportTorrent (firstStepDone)="onFirstStepDone('import-torrent', $event)" (firstStepError)="onError()"></my-video-import-torrent>
</ng-template>
</ngb-tab>
</ngb-tabset>

View File

@ -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()

View File

@ -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.' })