Congratulations! Your video is now available in your private library.
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 52a77f83f..ed817bff7 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
@@ -15,31 +15,3 @@
margin: 30px 0;
}
}
-
-.upload-progress-retry,
-.upload-progress-cancel {
- display: flex;
- margin-bottom: 40px;
-
- .progress {
- @include progressbar;
-
- flex-grow: 1;
- height: 30px;
- font-size: 14px;
- background-color: rgba(11, 204, 41, 0.16);
-
- .progress-bar {
- background-color: $green;
- line-height: 30px;
- text-align: start;
- font-weight: $font-semibold;
-
- span {
- @include margin-left(13px);
-
- color: pvar(--mainBackgroundColor);
- }
- }
- }
-}
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 967fa9ed1..cfa42910b 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
@@ -1,19 +1,18 @@
import { truncate } from 'lodash-es'
-import { UploadState, UploadxOptions, UploadxService } from 'ngx-uploadx'
-import { HttpErrorResponse, HttpEventType, HttpHeaders } from '@angular/common/http'
+import { UploadState, UploadxService } from 'ngx-uploadx'
+import { Subscription } from 'rxjs'
+import { HttpErrorResponse } from '@angular/common/http'
import { AfterViewInit, Component, ElementRef, EventEmitter, OnDestroy, OnInit, Output, ViewChild } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'
import { AuthService, CanComponentDeactivate, HooksService, MetaService, Notifier, ServerService, UserService } from '@app/core'
import { genericUploadErrorHandler, scrollToTop } from '@app/helpers'
import { FormReactiveService } from '@app/shared/shared-forms'
-import { BytesPipe, Video, VideoCaptionService, VideoEdit, VideoService } from '@app/shared/shared-main'
+import { Video, VideoCaptionService, VideoEdit, VideoService } from '@app/shared/shared-main'
import { LoadingBarService } from '@ngx-loading-bar/core'
import { logger } from '@root-helpers/logger'
-import { isIOS } from '@root-helpers/web-browser'
import { HttpStatusCode, VideoCreateResult } from '@shared/models'
-import { UploaderXFormData } from './uploaderx-form-data'
+import { VideoUploadService } from '../shared/video-upload.service'
import { VideoSend } from './video-send'
-import { Subscription } from 'rxjs'
@Component({
selector: 'my-video-upload',
@@ -49,9 +48,6 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
error: string
enableRetryAfterError: boolean
- // So that it can be accessed in the template
- protected readonly BASE_VIDEO_UPLOAD_URL = VideoService.BASE_VIDEO_URL + '/upload-resumable'
-
private isUpdatingVideo = false
private fileToUpload: File
@@ -72,15 +68,12 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
private hooks: HooksService,
private resumableUploadService: UploadxService,
private metaService: MetaService,
- private route: ActivatedRoute
+ private route: ActivatedRoute,
+ private videoUploadService: VideoUploadService
) {
super()
}
- get videoExtensions () {
- return this.serverConfig.video.file.extensions.join(', ')
- }
-
ngOnInit () {
super.ngOnInit()
@@ -133,28 +126,20 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
}
}
+ getVideoExtensions () {
+ return this.videoUploadService.getVideoExtensions().join(', ')
+ }
+
onUploadVideoOngoing (state: UploadState) {
switch (state.status) {
case 'error': {
if (!this.alreadyRefreshedToken && state.responseStatus === HttpStatusCode.UNAUTHORIZED_401) {
this.alreadyRefreshedToken = true
- return this.refereshTokenAndRetryUpload()
+ return this.refreshTokenAndRetryUpload()
}
- const error = state.response?.error?.message || state.response?.error || 'Unknown error'
-
- this.handleUploadError({
- error: new Error(error),
- name: 'HttpErrorResponse',
- message: error,
- ok: false,
- headers: new HttpHeaders(state.responseHeaders),
- status: +state.responseStatus,
- statusText: error,
- type: HttpEventType.Response,
- url: state.url
- })
+ this.handleUploadError(this.videoUploadService.buildHTTPErrorResponse(state))
break
}
@@ -203,10 +188,12 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
if (!file) return
- if (!this.checkGlobalUserQuota(file)) return
- if (!this.checkDailyUserQuota(file)) return
+ const user = this.authService.getUser()
- if (this.isAudioFile(file.name)) {
+ if (!this.videoUploadService.checkQuotaAndNotify(file, user.videoQuota, this.userVideoQuotaUsed)) return
+ if (!this.videoUploadService.checkQuotaAndNotify(file, user.videoQuotaDaily, this.userVideoQuotaUsedDaily)) return
+
+ if (this.videoUploadService.isAudioFile(file.name)) {
this.isUploadingAudioFile = true
return
}
@@ -291,7 +278,7 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
}
this.resumableUploadService.handleFiles(file, {
- ...this.getUploadxOptions(),
+ ...this.videoUploadService.getNewUploadxOptions(),
metadata
})
@@ -331,51 +318,6 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
this.updateTitle()
}
- private checkGlobalUserQuota (videofile: File) {
- const bytePipes = new BytesPipe()
-
- // Check global user quota
- const videoQuota = this.authService.getUser().videoQuota
- if (videoQuota !== -1 && (this.userVideoQuotaUsed + videofile.size) > videoQuota) {
- const videoSizeBytes = bytePipes.transform(videofile.size, 0)
- const videoQuotaUsedBytes = bytePipes.transform(this.userVideoQuotaUsed, 0)
- const videoQuotaBytes = bytePipes.transform(videoQuota, 0)
-
- // eslint-disable-next-line max-len
- const msg = $localize`Your video quota is exceeded with this video (video size: ${videoSizeBytes}, used: ${videoQuotaUsedBytes}, quota: ${videoQuotaBytes})`
- this.notifier.error(msg)
-
- return false
- }
-
- return true
- }
-
- private checkDailyUserQuota (videofile: File) {
- const bytePipes = new BytesPipe()
-
- // Check daily user quota
- const videoQuotaDaily = this.authService.getUser().videoQuotaDaily
- if (videoQuotaDaily !== -1 && (this.userVideoQuotaUsedDaily + videofile.size) > videoQuotaDaily) {
- const videoSizeBytes = bytePipes.transform(videofile.size, 0)
- const quotaUsedDailyBytes = bytePipes.transform(this.userVideoQuotaUsedDaily, 0)
- const quotaDailyBytes = bytePipes.transform(videoQuotaDaily, 0)
- // eslint-disable-next-line max-len
- const msg = $localize`Your daily video quota is exceeded with this video (video size: ${videoSizeBytes}, used: ${quotaUsedDailyBytes}, quota: ${quotaDailyBytes})`
- this.notifier.error(msg)
-
- return false
- }
-
- return true
- }
-
- private isAudioFile (filename: string) {
- const extensions = [ '.mp3', '.flac', '.ogg', '.wma', '.wav' ]
-
- return extensions.some(e => filename.endsWith(e))
- }
-
private buildVideoFilename (filename: string) {
const nameWithoutExtension = filename.replace(/\.[^/.]+$/, '')
let name = nameWithoutExtension.length < 3
@@ -390,35 +332,8 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
return name
}
- private refereshTokenAndRetryUpload () {
+ private refreshTokenAndRetryUpload () {
this.authService.refreshAccessToken()
.subscribe(() => this.retryUpload())
}
-
- private getUploadxOptions (): UploadxOptions {
- // FIXME: https://github.com/Chocobozzz/PeerTube/issues/4382#issuecomment-915854167
- const chunkSize = isIOS()
- ? 0
- : undefined // Auto chunk size
-
- return {
- endpoint: this.BASE_VIDEO_UPLOAD_URL,
- multiple: false,
-
- maxChunkSize: this.serverConfig.client.videos.resumableUpload.maxChunkSize,
- chunkSize,
-
- token: this.authService.getAccessToken(),
-
- uploaderClass: UploaderXFormData,
-
- retryConfig: {
- maxAttempts: 30, // maximum attempts for 503 codes, otherwise set to 6, see below
- maxDelay: 120_000, // 2 min
- shouldRetry: (code: number, attempts: number) => {
- return code === HttpStatusCode.SERVICE_UNAVAILABLE_503 || ((code < 400 || code > 500) && attempts < 6)
- }
- }
- }
- }
}
diff --git a/client/src/app/+videos/+video-edit/video-update.component.html b/client/src/app/+videos/+video-edit/video-update.component.html
index af564aeb0..9a99c0c3d 100644
--- a/client/src/app/+videos/+video-edit/video-update.component.html
+++ b/client/src/app/+videos/+video-edit/video-update.component.html
@@ -4,6 +4,12 @@
{{ videoDetails?.name }}