mirror of
https://github.com/Chocobozzz/PeerTube.git
synced 2024-11-25 18:20:31 -06:00
First step upload with new design
This commit is contained in:
parent
4cc66133ab
commit
27e1a06c33
@ -67,6 +67,7 @@
|
||||
<div class="form-group">
|
||||
<label for="privacy">Privacy</label>
|
||||
<select id="privacy" formControlName="privacy">
|
||||
|
||||
<option></option>
|
||||
<option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option>
|
||||
</select>
|
||||
|
@ -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 {
|
||||
font-size: 0.8em;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.label-tags {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
@ -1,141 +1,45 @@
|
||||
<div class="row">
|
||||
<div class="content-padding">
|
||||
<div class="margin-content">
|
||||
<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="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input
|
||||
type="text" class="form-control" id="name"
|
||||
formControlName="name"
|
||||
>
|
||||
<div *ngIf="formErrors.name" class="alert alert-danger">
|
||||
{{ formErrors.name }}
|
||||
</div>
|
||||
<div class="button-file">
|
||||
<span>Select the file to upload</span>
|
||||
<input #videofileInput type="file" name="videofile" id="videofile" (change)="fileChange($event)" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="privacy">Privacy</label>
|
||||
<select class="form-control" id="privacy" formControlName="privacy">
|
||||
<option></option>
|
||||
<select [(ngModel)]="firstStepPrivacy">
|
||||
<option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option>
|
||||
</select>
|
||||
|
||||
<div *ngIf="formErrors.privacy" class="alert alert-danger">
|
||||
{{ formErrors.privacy }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<input
|
||||
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">
|
||||
<select [(ngModel)]="firstStepChannel">
|
||||
<option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option>
|
||||
</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 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>
|
||||
</div>
|
||||
</div>
|
||||
|
60
client/src/app/videos/+video-edit/video-add.component.scss
Normal file
60
client/src/app/videos/+video-edit/video-add.component.scss
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,61 +6,33 @@ import { NotificationsService } from 'angular2-notifications'
|
||||
import { VideoService } from 'app/shared/video/video.service'
|
||||
import { VideoCreate } from '../../../../../shared'
|
||||
import { AuthService, ServerService } from '../../core'
|
||||
import {
|
||||
FormReactive,
|
||||
VIDEO_CATEGORY,
|
||||
VIDEO_CHANNEL,
|
||||
VIDEO_DESCRIPTION,
|
||||
VIDEO_FILE,
|
||||
VIDEO_LANGUAGE,
|
||||
VIDEO_LICENCE,
|
||||
VIDEO_NAME,
|
||||
VIDEO_PRIVACY,
|
||||
VIDEO_TAGS
|
||||
} from '../../shared'
|
||||
import { FormReactive } from '../../shared'
|
||||
import { ValidatorMessage } from '../../shared/forms/form-validators'
|
||||
import { VideoEdit } from '../../shared/video/video-edit.model'
|
||||
|
||||
@Component({
|
||||
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 {
|
||||
@ViewChild('videofileInput') videofileInput
|
||||
|
||||
isUploadingVideo = false
|
||||
progressPercent = 0
|
||||
tags: string[] = []
|
||||
videoCategories = []
|
||||
videoLicences = []
|
||||
videoLanguages = []
|
||||
videoPrivacies = []
|
||||
userVideoChannels = []
|
||||
|
||||
tagValidators = VIDEO_TAGS.VALIDATORS
|
||||
tagValidatorsMessages = VIDEO_TAGS.MESSAGES
|
||||
|
||||
error: string
|
||||
error: string = null
|
||||
form: FormGroup
|
||||
formErrors = {
|
||||
name: '',
|
||||
privacy: '',
|
||||
category: '',
|
||||
licence: '',
|
||||
language: '',
|
||||
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
|
||||
}
|
||||
formErrors: { [ id: string ]: string } = {}
|
||||
validationMessages: ValidatorMessage = {}
|
||||
userVideoChannels = []
|
||||
videoPrivacies = []
|
||||
firstStepPrivacy = 0
|
||||
firstStepChannel = 0
|
||||
|
||||
constructor (
|
||||
private formBuilder: FormBuilder,
|
||||
@ -73,35 +45,17 @@ export class VideoAddComponent extends FormReactive implements OnInit {
|
||||
super()
|
||||
}
|
||||
|
||||
get filename () {
|
||||
return this.form.value['videofile']
|
||||
}
|
||||
|
||||
buildForm () {
|
||||
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 = this.formBuilder.group({})
|
||||
this.form.valueChanges.subscribe(data => this.onValueChanged(data))
|
||||
}
|
||||
|
||||
ngOnInit () {
|
||||
this.videoCategories = this.serverService.getVideoCategories()
|
||||
this.videoLicences = this.serverService.getVideoLicences()
|
||||
this.videoLanguages = this.serverService.getVideoLanguages()
|
||||
this.videoPrivacies = this.serverService.getVideoPrivacies()
|
||||
|
||||
this.buildForm()
|
||||
|
||||
this.videoPrivacies = this.serverService.getVideoPrivacies()
|
||||
this.firstStepPrivacy = this.videoPrivacies[0].id
|
||||
|
||||
this.authService.userInformationLoaded
|
||||
.subscribe(
|
||||
() => {
|
||||
@ -112,21 +66,13 @@ export class VideoAddComponent extends FormReactive implements OnInit {
|
||||
if (Array.isArray(videoChannels) === false) return
|
||||
|
||||
this.userVideoChannels = videoChannels.map(v => ({ id: v.id, label: v.name }))
|
||||
|
||||
this.form.patchValue({ channelId: this.userVideoChannels[0].id })
|
||||
this.firstStepChannel = this.userVideoChannels[0].id
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// The goal is to keep reactive form validation (required field)
|
||||
// https://stackoverflow.com/a/44238894
|
||||
fileChange ($event) {
|
||||
this.form.controls['videofile'].setValue($event.target.files[0].name)
|
||||
}
|
||||
|
||||
removeFile () {
|
||||
this.videofileInput.nativeElement.value = ''
|
||||
this.form.controls['videofile'].setValue('')
|
||||
console.log('uploading file ?')
|
||||
}
|
||||
|
||||
checkForm () {
|
||||
@ -135,11 +81,7 @@ export class VideoAddComponent extends FormReactive implements OnInit {
|
||||
return this.form.valid
|
||||
}
|
||||
|
||||
upload () {
|
||||
if (this.checkForm() === false) {
|
||||
return
|
||||
}
|
||||
|
||||
uploadFirstStep () {
|
||||
const formValue: VideoCreate = this.form.value
|
||||
|
||||
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)
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
|
16
client/src/assets/images/video/upload.svg
Normal file
16
client/src/assets/images/video/upload.svg
Normal 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 |
Loading…
Reference in New Issue
Block a user