First step upload with new design

This commit is contained in:
Chocobozzz 2017-12-07 16:32:06 +01:00
parent 4cc66133ab
commit 27e1a06c33
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
6 changed files with 148 additions and 238 deletions

View File

@ -67,6 +67,7 @@
<div class="form-group"> <div class="form-group">
<label for="privacy">Privacy</label> <label for="privacy">Privacy</label>
<select id="privacy" formControlName="privacy"> <select id="privacy" formControlName="privacy">
<option></option> <option></option>
<option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option> <option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option>
</select> </select>

View File

@ -115,42 +115,7 @@
} }
} }
.btn-file {
position: relative;
overflow: hidden;
display: block;
}
.btn-file input[type=file] {
position: absolute;
top: 0;
right: 0;
min-width: 100%;
min-height: 100%;
font-size: 100px;
text-align: right;
filter: alpha(opacity=0);
opacity: 0;
outline: none;
background: white;
cursor: inherit;
display: block;
}
div.file-to-upload {
height: 40px;
.glyphicon-remove {
cursor: pointer;
}
}
.little-information { .little-information {
font-size: 0.8em; font-size: 0.8em;
font-style: italic; font-style: italic;
} }
.label-tags {
margin-bottom: 0;
}

View File

@ -1,141 +1,45 @@
<div class="row"> <div class="margin-content">
<div class="content-padding"> <div class="title-page title-page-single">
Upload your video
</div>
<h3>Upload a video</h3> <div *ngIf="error" class="alert alert-danger">{{ error }}</div>
<div *ngIf="error !== undefined" class="alert alert-danger">{{ error }}</div> <div class="upload-video-container">
<div class="upload-video">
<div class="icon icon-upload"></div>
<form novalidate [formGroup]="form"> <div class="button-file">
<div class="form-group"> <span>Select the file to upload</span>
<label for="name">Name</label> <input #videofileInput type="file" name="videofile" id="videofile" (change)="fileChange($event)" />
<input
type="text" class="form-control" id="name"
formControlName="name"
>
<div *ngIf="formErrors.name" class="alert alert-danger">
{{ formErrors.name }}
</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="privacy">Privacy</label> <select [(ngModel)]="firstStepPrivacy">
<select class="form-control" id="privacy" formControlName="privacy">
<option></option>
<option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option> <option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option>
</select> </select>
<div *ngIf="formErrors.privacy" class="alert alert-danger">
{{ formErrors.privacy }}
</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<input <select [(ngModel)]="firstStepChannel">
type="checkbox" id="nsfw"
formControlName="nsfw"
>
<label for="nsfw">This video contains mature or explicit content</label>
</div>
<div class="form-group">
<label for="category">Channel</label>
<select class="form-control" id="channelId" formControlName="channelId">
<option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option> <option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option>
</select> </select>
</div>
</div>
<div *ngIf="formErrors.channelId" class="alert alert-danger">
{{ formErrors.channelId }} <form *ngIf="isUploadingVideo" novalidate [formGroup]="form">
<my-video-edit
[form]="form" [formErrors]="formErrors"
[validationMessages]="validationMessages" [videoPrivacies]="videoPrivacies"
></my-video-edit>
<div class="submit-container">
<div class="submit-button" [ngClass]="{ disabled: !form.valid }">
<span class="icon icon-validate"></span>
<input type="button" value="Publish" (click)="upload()" />
</div> </div>
</div> </div>
<div class="form-group">
<label for="category">Category</label>
<select class="form-control" id="category" formControlName="category">
<option></option>
<option *ngFor="let category of videoCategories" [value]="category.id">{{ category.label }}</option>
</select>
<div *ngIf="formErrors.category" class="alert alert-danger">
{{ formErrors.category }}
</div>
</div>
<div class="form-group">
<label for="licence">Licence</label>
<select class="form-control" id="licence" formControlName="licence">
<option></option>
<option *ngFor="let licence of videoLicences" [value]="licence.id">{{ licence.label }}</option>
</select>
<div *ngIf="formErrors.licence" class="alert alert-danger">
{{ formErrors.licence }}
</div>
</div>
<div class="form-group">
<label for="language">Language</label>
<select class="form-control" id="language" formControlName="language">
<option></option>
<option *ngFor="let language of videoLanguages" [value]="language.id">{{ language.label }}</option>
</select>
<div *ngIf="formErrors.language" class="alert alert-danger">
{{ formErrors.language }}
</div>
</div>
<div class="form-group">
<label class="label-tags">Tags</label> <span class="little-information">(press enter to add the tag)</span>
<tag-input
[ngModel]="tags" [validators]="tagValidators" [errorMessages]="tagValidatorsMessages"
formControlName="tags" maxItems="5" modelAsStrings="true"
></tag-input>
</div>
<div class="form-group">
<label for="videofile">File</label>
<div class="btn btn-default btn-file">
<span>Select the video...</span>
<input #videofileInput type="file" name="videofile" id="videofile" (change)="fileChange($event)" />
<input type="hidden" name="videofileHidden" formControlName="videofile"/>
</div>
</div>
<div class="file-to-upload">
<div class="file" *ngIf="filename">
<span class="filename">{{ filename }}</span>
<span class="glyphicon glyphicon-remove" (click)="removeFile()"></span>
</div>
</div>
<div *ngIf="formErrors.videofile" class="alert alert-danger">
{{ formErrors.videofile }}
</div>
<div class="form-group">
<label for="description">Description</label>
<my-video-description formControlName="description"></my-video-description>
<div *ngIf="formErrors.description" class="alert alert-danger">
{{ formErrors.description }}
</div>
</div>
<div class="progress">
<progressbar [value]="progressPercent" max="100">
<ng-template [ngIf]="progressPercent === 100">
<span class="glyphicon glyphicon-refresh glyphicon-refresh-animate"></span>
Server is processing the video
</ng-template>
</progressbar>
</div>
<div class="form-group">
<input
type="button" value="Upload" class="btn btn-default form-control"
(click)="upload()"
>
</div>
</form> </form>
</div> </div>
</div> </div>

View File

@ -0,0 +1,60 @@
.upload-video-container {
border-radius: 3px;
background-color: #F7F7F7;
border: 3px solid #EAEAEA;
width: 100%;
height: 440px;
text-align: center;
margin-top: 40px;
display: flex;
justify-content: center;
align-items: center;
.upload-video {
display: flex;
flex-direction: column;
align-items: center;
.icon.icon-upload {
@include icon(90px);
margin-bottom: 25px;
background-image: url('../../../assets/images/video/upload.svg');
}
.button-file {
position: relative;
overflow: hidden;
display: inline-block;
margin-bottom: 70px;
@include peertube-button;
@include orange-button;
input[type=file] {
position: absolute;
top: 0;
right: 0;
min-width: 100%;
min-height: 100%;
font-size: 100px;
text-align: right;
filter: alpha(opacity=0);
opacity: 0;
outline: none;
background: white;
cursor: inherit;
display: block;
}
}
select {
@include peertube-select(auto);
display: inline-block;
font-size: 15px
}
}
}

View File

@ -6,61 +6,33 @@ import { NotificationsService } from 'angular2-notifications'
import { VideoService } from 'app/shared/video/video.service' import { VideoService } from 'app/shared/video/video.service'
import { VideoCreate } from '../../../../../shared' import { VideoCreate } from '../../../../../shared'
import { AuthService, ServerService } from '../../core' import { AuthService, ServerService } from '../../core'
import { import { FormReactive } from '../../shared'
FormReactive, import { ValidatorMessage } from '../../shared/forms/form-validators'
VIDEO_CATEGORY, import { VideoEdit } from '../../shared/video/video-edit.model'
VIDEO_CHANNEL,
VIDEO_DESCRIPTION,
VIDEO_FILE,
VIDEO_LANGUAGE,
VIDEO_LICENCE,
VIDEO_NAME,
VIDEO_PRIVACY,
VIDEO_TAGS
} from '../../shared'
@Component({ @Component({
selector: 'my-videos-add', selector: 'my-videos-add',
styleUrls: [ './shared/video-edit.component.scss' ], templateUrl: './video-add.component.html',
templateUrl: './video-add.component.html' styleUrls: [
'./shared/video-edit.component.scss',
'./video-add.component.scss'
]
}) })
export class VideoAddComponent extends FormReactive implements OnInit { export class VideoAddComponent extends FormReactive implements OnInit {
@ViewChild('videofileInput') videofileInput @ViewChild('videofileInput') videofileInput
isUploadingVideo = false
progressPercent = 0 progressPercent = 0
tags: string[] = []
videoCategories = []
videoLicences = []
videoLanguages = []
videoPrivacies = []
userVideoChannels = []
tagValidators = VIDEO_TAGS.VALIDATORS error: string = null
tagValidatorsMessages = VIDEO_TAGS.MESSAGES
error: string
form: FormGroup form: FormGroup
formErrors = { formErrors: { [ id: string ]: string } = {}
name: '', validationMessages: ValidatorMessage = {}
privacy: '', userVideoChannels = []
category: '', videoPrivacies = []
licence: '', firstStepPrivacy = 0
language: '', firstStepChannel = 0
channelId: '',
description: '',
videofile: ''
}
validationMessages = {
name: VIDEO_NAME.MESSAGES,
privacy: VIDEO_PRIVACY.MESSAGES,
category: VIDEO_CATEGORY.MESSAGES,
licence: VIDEO_LICENCE.MESSAGES,
language: VIDEO_LANGUAGE.MESSAGES,
channelId: VIDEO_CHANNEL.MESSAGES,
description: VIDEO_DESCRIPTION.MESSAGES,
videofile: VIDEO_FILE.MESSAGES
}
constructor ( constructor (
private formBuilder: FormBuilder, private formBuilder: FormBuilder,
@ -73,35 +45,17 @@ export class VideoAddComponent extends FormReactive implements OnInit {
super() super()
} }
get filename () {
return this.form.value['videofile']
}
buildForm () { buildForm () {
this.form = this.formBuilder.group({ this.form = this.formBuilder.group({})
name: [ '', VIDEO_NAME.VALIDATORS ],
nsfw: [ false ],
privacy: [ '', VIDEO_PRIVACY.VALIDATORS ],
category: [ '', VIDEO_CATEGORY.VALIDATORS ],
licence: [ '', VIDEO_LICENCE.VALIDATORS ],
language: [ '', VIDEO_LANGUAGE.VALIDATORS ],
channelId: [ '', VIDEO_CHANNEL.VALIDATORS ],
description: [ '', VIDEO_DESCRIPTION.VALIDATORS ],
videofile: [ '', VIDEO_FILE.VALIDATORS ],
tags: [ '' ]
})
this.form.valueChanges.subscribe(data => this.onValueChanged(data)) this.form.valueChanges.subscribe(data => this.onValueChanged(data))
} }
ngOnInit () { ngOnInit () {
this.videoCategories = this.serverService.getVideoCategories()
this.videoLicences = this.serverService.getVideoLicences()
this.videoLanguages = this.serverService.getVideoLanguages()
this.videoPrivacies = this.serverService.getVideoPrivacies()
this.buildForm() this.buildForm()
this.videoPrivacies = this.serverService.getVideoPrivacies()
this.firstStepPrivacy = this.videoPrivacies[0].id
this.authService.userInformationLoaded this.authService.userInformationLoaded
.subscribe( .subscribe(
() => { () => {
@ -112,21 +66,13 @@ export class VideoAddComponent extends FormReactive implements OnInit {
if (Array.isArray(videoChannels) === false) return if (Array.isArray(videoChannels) === false) return
this.userVideoChannels = videoChannels.map(v => ({ id: v.id, label: v.name })) this.userVideoChannels = videoChannels.map(v => ({ id: v.id, label: v.name }))
this.firstStepChannel = this.userVideoChannels[0].id
this.form.patchValue({ channelId: this.userVideoChannels[0].id })
} }
) )
} }
// The goal is to keep reactive form validation (required field)
// https://stackoverflow.com/a/44238894
fileChange ($event) { fileChange ($event) {
this.form.controls['videofile'].setValue($event.target.files[0].name) console.log('uploading file ?')
}
removeFile () {
this.videofileInput.nativeElement.value = ''
this.form.controls['videofile'].setValue('')
} }
checkForm () { checkForm () {
@ -135,11 +81,7 @@ export class VideoAddComponent extends FormReactive implements OnInit {
return this.form.valid return this.form.valid
} }
upload () { uploadFirstStep () {
if (this.checkForm() === false) {
return
}
const formValue: VideoCreate = this.form.value const formValue: VideoCreate = this.form.value
const name = formValue.name const name = formValue.name
@ -193,4 +135,26 @@ export class VideoAddComponent extends FormReactive implements OnInit {
} }
) )
} }
updateSecondStep () {
if (this.checkForm() === false) {
return
}
const video = new VideoEdit(this.form.value)
this.videoService.updateVideo(video)
.subscribe(
() => {
this.notificationsService.success('Success', 'Video published.')
this.router.navigate([ '/videos/watch', video.uuid ])
},
err => {
this.error = 'Cannot update the video.'
console.error(err)
}
)
}
} }

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
<title>cloud-upload</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
<g id="Artboard-4" transform="translate(-312.000000, -775.000000)" stroke="#C6C6C6" stroke-width="2">
<g id="307" transform="translate(312.000000, 775.000000)">
<path d="M8,18 L5,18 L5,18 C2.790861,18 1,16.209139 1,14 C1,11.790861 2.790861,10 5,10 C5.35840468,10 5.70579988,10.0471371 6.03632437,10.1355501 C6.01233106,9.92702603 6,9.71495305 6,9.5 C6,6.46243388 8.46243388,4 11.5,4 C14.0673313,4 16.2238156,5.7590449 16.8299648,8.1376465 C17.2052921,8.04765874 17.5970804,8 18,8 C20.7614237,8 23,10.2385763 23,13 C23,15.7614237 20.7614237,18 18,18 L16,18" id="Combined-Shape" stroke-linejoin="round"></path>
<path d="M12,13 L12,21" id="Path-58"></path>
<polyline id="Path-59" stroke-linejoin="round" transform="translate(12.000000, 12.500000) scale(1, -1) translate(-12.000000, -12.500000) " points="15 11 12 14 9 11"></polyline>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB