From cadb46d832724ea1a17b085b992142aa32e212be Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 8 Dec 2017 08:39:15 +0100 Subject: Design second video upload step --- client/src/app/core/auth/auth.service.ts | 3 +- client/src/app/core/server/server.service.ts | 3 +- client/src/app/menu/menu.component.scss | 4 ++ .../src/app/shared/forms/form-validators/video.ts | 22 ++----- client/src/app/shared/video/video-edit.model.ts | 26 +++++---- client/src/app/shared/video/video.service.ts | 11 ++-- .../shared/video-description.component.html | 9 +++ .../shared/video-description.component.scss | 41 +++++++++++++ .../shared/video-description.component.ts | 66 +++++++++++++++++++++ .../+video-edit/shared/video-edit.component.scss | 9 +++ .../videos/+video-edit/shared/video-edit.module.ts | 3 +- .../videos/+video-edit/video-add.component.html | 16 +++-- .../videos/+video-edit/video-add.component.scss | 19 +++++- .../app/videos/+video-edit/video-add.component.ts | 30 ++++++---- .../videos/+video-edit/video-update.component.html | 4 +- .../videos/+video-watch/video-watch.component.html | 2 +- .../videos/+video-watch/video-watch.component.ts | 5 ++ client/src/app/videos/shared/index.ts | 1 - .../videos/shared/video-description.component.html | 9 --- .../videos/shared/video-description.component.scss | 19 ------ .../videos/shared/video-description.component.ts | 68 ---------------------- client/src/sass/_mixins.scss | 6 +- client/src/sass/application.scss | 4 ++ 23 files changed, 224 insertions(+), 156 deletions(-) create mode 100644 client/src/app/videos/+video-edit/shared/video-description.component.html create mode 100644 client/src/app/videos/+video-edit/shared/video-description.component.scss create mode 100644 client/src/app/videos/+video-edit/shared/video-description.component.ts delete mode 100644 client/src/app/videos/shared/video-description.component.html delete mode 100644 client/src/app/videos/shared/video-description.component.scss delete mode 100644 client/src/app/videos/shared/video-description.component.ts (limited to 'client') diff --git a/client/src/app/core/auth/auth.service.ts b/client/src/app/core/auth/auth.service.ts index fd2708c11..0db197f02 100644 --- a/client/src/app/core/auth/auth.service.ts +++ b/client/src/app/core/auth/auth.service.ts @@ -194,7 +194,6 @@ export class AuthService { } this.mergeUserInformation(obj) - .do(() => this.userInformationLoaded.next(true)) .subscribe( res => { this.user.displayNSFW = res.displayNSFW @@ -203,6 +202,8 @@ export class AuthService { this.user.account = res.account this.user.save() + + this.userInformationLoaded.next(true) } ) } diff --git a/client/src/app/core/server/server.service.ts b/client/src/app/core/server/server.service.ts index 43a836c5a..16e0595b6 100644 --- a/client/src/app/core/server/server.service.ts +++ b/client/src/app/core/server/server.service.ts @@ -77,7 +77,6 @@ export class ServerService { notifier: ReplaySubject ) { return this.http.get(ServerService.BASE_VIDEO_URL + attributeName) - .do(() => notifier.next(true)) .subscribe(data => { Object.keys(data) .forEach(dataKey => { @@ -86,6 +85,8 @@ export class ServerService { label: data[dataKey] }) }) + + notifier.next(true) }) } } diff --git a/client/src/app/menu/menu.component.scss b/client/src/app/menu/menu.component.scss index eda3e1a85..63d63d287 100644 --- a/client/src/app/menu/menu.component.scss +++ b/client/src/app/menu/menu.component.scss @@ -43,6 +43,10 @@ menu { .logged-in-email { font-size: 13px; color: #C6C6C6; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 140px; } } diff --git a/client/src/app/shared/forms/form-validators/video.ts b/client/src/app/shared/forms/form-validators/video.ts index 8e512e8c8..45da7df4a 100644 --- a/client/src/app/shared/forms/form-validators/video.ts +++ b/client/src/app/shared/forms/form-validators/video.ts @@ -23,17 +23,13 @@ export const VIDEO_PRIVACY = { } export const VIDEO_CATEGORY = { - VALIDATORS: [ Validators.required ], - MESSAGES: { - 'required': 'Video category is required.' - } + VALIDATORS: [ ], + MESSAGES: {} } export const VIDEO_LICENCE = { - VALIDATORS: [ Validators.required ], - MESSAGES: { - 'required': 'Video licence is required.' - } + VALIDATORS: [ ], + MESSAGES: {} } export const VIDEO_LANGUAGE = { @@ -49,9 +45,8 @@ export const VIDEO_CHANNEL = { } export const VIDEO_DESCRIPTION = { - VALIDATORS: [ Validators.required, Validators.minLength(3), Validators.maxLength(3000) ], + VALIDATORS: [ Validators.minLength(3), Validators.maxLength(3000) ], MESSAGES: { - 'required': 'Video description is required.', 'minlength': 'Video description must be at least 3 characters long.', 'maxlength': 'Video description cannot be more than 3000 characters long.' } @@ -64,10 +59,3 @@ export const VIDEO_TAGS = { 'maxlength': 'A tag should be less than 30 characters long.' } } - -export const VIDEO_FILE = { - VALIDATORS: [ Validators.required ], - MESSAGES: { - 'required': 'Video file is required.' - } -} diff --git a/client/src/app/shared/video/video-edit.model.ts b/client/src/app/shared/video/video-edit.model.ts index 88d23a59f..955255bfa 100644 --- a/client/src/app/shared/video/video-edit.model.ts +++ b/client/src/app/shared/video/video-edit.model.ts @@ -14,18 +14,20 @@ export class VideoEdit { uuid?: string id?: number - constructor (videoDetails: VideoDetails) { - this.id = videoDetails.id - this.uuid = videoDetails.uuid - this.category = videoDetails.category - this.licence = videoDetails.licence - this.language = videoDetails.language - this.description = videoDetails.description - this.name = videoDetails.name - this.tags = videoDetails.tags - this.nsfw = videoDetails.nsfw - this.channel = videoDetails.channel.id - this.privacy = videoDetails.privacy + constructor (videoDetails?: VideoDetails) { + if (videoDetails) { + this.id = videoDetails.id + this.uuid = videoDetails.uuid + this.category = videoDetails.category + this.licence = videoDetails.licence + this.language = videoDetails.language + this.description = videoDetails.description + this.name = videoDetails.name + this.tags = videoDetails.tags + this.nsfw = videoDetails.nsfw + this.channel = videoDetails.channel.id + this.privacy = videoDetails.privacy + } } patch (values: Object) { diff --git a/client/src/app/shared/video/video.service.ts b/client/src/app/shared/video/video.service.ts index 3f35b67c4..1a0644c3d 100644 --- a/client/src/app/shared/video/video.service.ts +++ b/client/src/app/shared/video/video.service.ts @@ -42,14 +42,17 @@ export class VideoService { } updateVideo (video: VideoEdit) { - const language = video.language ? video.language : null + const language = video.language || undefined + const licence = video.licence || undefined + const category = video.category || undefined + const description = video.description || undefined const body: VideoUpdate = { name: video.name, - category: video.category, - licence: video.licence, + category, + licence, language, - description: video.description, + description, privacy: video.privacy, tags: video.tags, nsfw: video.nsfw diff --git a/client/src/app/videos/+video-edit/shared/video-description.component.html b/client/src/app/videos/+video-edit/shared/video-description.component.html new file mode 100644 index 000000000..da66a9753 --- /dev/null +++ b/client/src/app/videos/+video-edit/shared/video-description.component.html @@ -0,0 +1,9 @@ + + + + + + diff --git a/client/src/app/videos/+video-edit/shared/video-description.component.scss b/client/src/app/videos/+video-edit/shared/video-description.component.scss new file mode 100644 index 000000000..38506bb46 --- /dev/null +++ b/client/src/app/videos/+video-edit/shared/video-description.component.scss @@ -0,0 +1,41 @@ +textarea { + @include peertube-input-text(100%); + + padding: 5px 15px; + font-size: 15px; + height: 150px; +} + +.previews /deep/ { + font-size: 15px !important; + + .nav { + margin-top: 10px; + font-size: 16px !important; + border: none !important; + + .nav-item .nav-link { + color: #000 !important; + height: 30px !important; + margin-right: 30px; + padding: 0 15px; + display: flex; + align-items: center; + border-radius: 3px; + border: none !important; + + &.active, &:hover { + background-color: #F0F0F0; + } + + &.active { + font-weight: $font-semibold !important; + } + } + } + + .tab-content { + min-height: 75px; + padding: 15px; + } +} diff --git a/client/src/app/videos/+video-edit/shared/video-description.component.ts b/client/src/app/videos/+video-edit/shared/video-description.component.ts new file mode 100644 index 000000000..8dfb74b2a --- /dev/null +++ b/client/src/app/videos/+video-edit/shared/video-description.component.ts @@ -0,0 +1,66 @@ +import { Component, forwardRef, Input, OnInit } from '@angular/core' +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' +import { truncate } from 'lodash' +import 'rxjs/add/operator/debounceTime' +import 'rxjs/add/operator/distinctUntilChanged' +import { Subject } from 'rxjs/Subject' +import { MarkdownService } from '../../shared' + +@Component({ + selector: 'my-video-description', + templateUrl: './video-description.component.html', + styleUrls: [ './video-description.component.scss' ], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => VideoDescriptionComponent), + multi: true + } + ] +}) + +export class VideoDescriptionComponent implements ControlValueAccessor, OnInit { + @Input() description = '' + truncatedDescriptionHTML = '' + descriptionHTML = '' + + private descriptionChanged = new Subject() + + constructor (private markdownService: MarkdownService) {} + + ngOnInit () { + this.descriptionChanged + .debounceTime(150) + .distinctUntilChanged() + .subscribe(() => this.updateDescriptionPreviews()) + + this.descriptionChanged.next(this.description) + } + + propagateChange = (_: any) => { /* empty */ } + + writeValue (description: string) { + this.description = description + + this.descriptionChanged.next(this.description) + } + + registerOnChange (fn: (_: any) => void) { + this.propagateChange = fn + } + + registerOnTouched () { + // Unused + } + + onModelChange () { + this.propagateChange(this.description) + + this.descriptionChanged.next(this.description) + } + + private updateDescriptionPreviews () { + this.truncatedDescriptionHTML = this.markdownService.markdownToHTML(truncate(this.description, { length: 250 })) + this.descriptionHTML = this.markdownService.markdownToHTML(this.description) + } +} diff --git a/client/src/app/videos/+video-edit/shared/video-edit.component.scss b/client/src/app/videos/+video-edit/shared/video-edit.component.scss index 2d0bfc36e..d363499ce 100644 --- a/client/src/app/videos/+video-edit/shared/video-edit.component.scss +++ b/client/src/app/videos/+video-edit/shared/video-edit.component.scss @@ -43,6 +43,14 @@ position: relative; bottom: $button-height; + .message-submit { + display: inline-block; + margin-right: 25px; + + color: #585858; + font-size: 15px; + } + .submit-button { @include peertube-button; @include orange-button; @@ -54,6 +62,7 @@ background-color: inherit; border: none; padding: 0; + outline: 0; } .icon.icon-validate { diff --git a/client/src/app/videos/+video-edit/shared/video-edit.module.ts b/client/src/app/videos/+video-edit/shared/video-edit.module.ts index c7ed8c351..ce106d82f 100644 --- a/client/src/app/videos/+video-edit/shared/video-edit.module.ts +++ b/client/src/app/videos/+video-edit/shared/video-edit.module.ts @@ -3,8 +3,9 @@ import { NgModule } from '@angular/core' import { TagInputModule } from 'ngx-chips' import { TabsModule } from 'ngx-bootstrap/tabs' -import { MarkdownService, VideoDescriptionComponent } from '../../shared' +import { MarkdownService } from '../../shared' import { SharedModule } from '../../../shared' +import { VideoDescriptionComponent } from './video-description.component' import { VideoEditComponent } from './video-edit.component' @NgModule({ 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 6883f8280..a6f2bf6f2 100644 --- a/client/src/app/videos/+video-edit/video-add.component.html +++ b/client/src/app/videos/+video-edit/video-add.component.html @@ -15,20 +15,23 @@
-
-
- +
@@ -37,10 +40,13 @@ [validationMessages]="validationMessages" [videoPrivacies]="videoPrivacies" > +
-
+
Publish will be available when upload is finished
+ +
- +
diff --git a/client/src/app/videos/+video-edit/video-add.component.scss b/client/src/app/videos/+video-edit/video-add.component.scss index dfdf7ff73..39673b4b7 100644 --- a/client/src/app/videos/+video-edit/video-add.component.scss +++ b/client/src/app/videos/+video-edit/video-add.component.scss @@ -18,6 +18,7 @@ .icon.icon-upload { @include icon(90px); margin-bottom: 25px; + cursor: default; background-image: url('../../../assets/images/video/upload.svg'); } @@ -58,10 +59,9 @@ } p-progressBar { - margin-top: 50px; - margin-bottom: 40px; - /deep/ .ui-progressbar { + margin-top: 25px !important; + margin-bottom: 40px !important; font-size: 15px !important; color: #fff !important; height: 30px !important; @@ -76,6 +76,19 @@ p-progressBar { .ui-progressbar-label { text-align: left; padding-left: 18px; + margin-top: 0 !important; + } + } + + &.processing { + /deep/ .ui-progressbar-label { + // Same color as background to hide "100%" + color: rgba(11, 204, 41, 0.16) !important; + + &::before { + content: 'Processing...'; + color: #fff; + } } } } 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 2409acfda..2bbc3de17 100644 --- a/client/src/app/videos/+video-edit/video-add.component.ts +++ b/client/src/app/videos/+video-edit/video-add.component.ts @@ -5,6 +5,7 @@ import { Router } from '@angular/router' import { NotificationsService } from 'angular2-notifications' import { VideoService } from 'app/shared/video/video.service' import { VideoCreate } from '../../../../../shared' +import { VideoPrivacy } from '../../../../../shared/models/videos' import { AuthService, ServerService } from '../../core' import { FormReactive } from '../../shared' import { ValidatorMessage } from '../../shared/forms/form-validators' @@ -25,6 +26,7 @@ export class VideoAddComponent extends FormReactive implements OnInit { isUploadingVideo = false videoUploaded = false videoUploadPercents = 0 + videoUploadedId = 0 error: string = null form: FormGroup @@ -33,8 +35,8 @@ export class VideoAddComponent extends FormReactive implements OnInit { userVideoChannels = [] videoPrivacies = [] - firstStepPrivacy = 0 - firstStepChannel = 0 + firstStepPrivacyId = 0 + firstStepChannelId = 0 constructor ( private formBuilder: FormBuilder, @@ -59,7 +61,9 @@ export class VideoAddComponent extends FormReactive implements OnInit { .subscribe( () => { this.videoPrivacies = this.serverService.getVideoPrivacies() - this.firstStepPrivacy = this.videoPrivacies[0].id + + // Public by default + this.firstStepPrivacyId = VideoPrivacy.PUBLIC }) this.authService.userInformationLoaded @@ -72,7 +76,7 @@ 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.firstStepChannel = this.userVideoChannels[0].id + this.firstStepChannelId = this.userVideoChannels[0].id } ) } @@ -89,14 +93,15 @@ export class VideoAddComponent extends FormReactive implements OnInit { uploadFirstStep () { const videofile = this.videofileInput.nativeElement.files[0] - const name = videofile.name - const privacy = this.firstStepPrivacy.toString() + const name = videofile.name.replace(/\.[^/.]+$/, '') + const privacy = this.firstStepPrivacyId.toString() const nsfw = false - const channelId = this.firstStepChannel.toString() + const channelId = this.firstStepChannelId.toString() const formData = new FormData() formData.append('name', name) - formData.append('privacy', privacy.toString()) + // Put the video "private" -> we wait he validates the second step + formData.append('privacy', VideoPrivacy.PRIVATE.toString()) formData.append('nsfw', '' + nsfw) formData.append('channelId', '' + channelId) formData.append('videofile', videofile) @@ -117,6 +122,8 @@ export class VideoAddComponent extends FormReactive implements OnInit { console.log('Video uploaded.') this.videoUploaded = true + + this.videoUploadedId = event.body.video.id } }, @@ -133,13 +140,16 @@ export class VideoAddComponent extends FormReactive implements OnInit { return } - const video = new VideoEdit(this.form.value) + const video = new VideoEdit() + video.patch(this.form.value) + video.channel = this.firstStepChannelId + video.id = this.videoUploadedId this.videoService.updateVideo(video) .subscribe( () => { this.notificationsService.success('Success', 'Video published.') - this.router.navigate([ '/videos/watch', video.uuid ]) + this.router.navigate([ '/videos/watch', video.id ]) }, err => { 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 3163495bf..261b8a130 100644 --- a/client/src/app/videos/+video-edit/video-update.component.html +++ b/client/src/app/videos/+video-edit/video-update.component.html @@ -11,9 +11,9 @@ >
-
+
- +
diff --git a/client/src/app/videos/+video-watch/video-watch.component.html b/client/src/app/videos/+video-watch/video-watch.component.html index 583da4685..dfed4768c 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.html +++ b/client/src/app/videos/+video-watch/video-watch.component.html @@ -78,7 +78,7 @@
-
+
Show more diff --git a/client/src/app/videos/+video-watch/video-watch.component.ts b/client/src/app/videos/+video-watch/video-watch.component.ts index 87db023bf..d4e3ec014 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.ts +++ b/client/src/app/videos/+video-watch/video-watch.component.ts @@ -219,6 +219,11 @@ export class VideoWatchComponent implements OnInit, OnDestroy { } private setVideoDescriptionHTML () { + if (!this.video.description) { + this.videoHTMLDescription = '' + return + } + this.videoHTMLDescription = this.markdownService.markdownToHTML(this.video.description) } diff --git a/client/src/app/videos/shared/index.ts b/client/src/app/videos/shared/index.ts index 3c72ed895..7a66944b9 100644 --- a/client/src/app/videos/shared/index.ts +++ b/client/src/app/videos/shared/index.ts @@ -1,2 +1 @@ export * from './markdown.service' -export * from './video-description.component' diff --git a/client/src/app/videos/shared/video-description.component.html b/client/src/app/videos/shared/video-description.component.html deleted file mode 100644 index da66a9753..000000000 --- a/client/src/app/videos/shared/video-description.component.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/client/src/app/videos/shared/video-description.component.scss b/client/src/app/videos/shared/video-description.component.scss deleted file mode 100644 index 6ef81ae58..000000000 --- a/client/src/app/videos/shared/video-description.component.scss +++ /dev/null @@ -1,19 +0,0 @@ -textarea { - @include peertube-input-text(100%); - - font-size: 15px; - height: 150px; -} - -.previews /deep/ { - font-size: 15px !important; - - .nav { - margin-top: 10px; - } - - .tab-content { - min-height: 75px; - padding: 5px; - } -} diff --git a/client/src/app/videos/shared/video-description.component.ts b/client/src/app/videos/shared/video-description.component.ts deleted file mode 100644 index d9ffb7800..000000000 --- a/client/src/app/videos/shared/video-description.component.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Component, forwardRef, Input, OnInit } from '@angular/core' -import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' -import { Subject } from 'rxjs/Subject' -import 'rxjs/add/operator/debounceTime' -import 'rxjs/add/operator/distinctUntilChanged' - -import { truncate } from 'lodash' - -import { MarkdownService } from './markdown.service' - -@Component({ - selector: 'my-video-description', - templateUrl: './video-description.component.html', - styleUrls: [ './video-description.component.scss' ], - providers: [ - { - provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => VideoDescriptionComponent), - multi: true - } - ] -}) - -export class VideoDescriptionComponent implements ControlValueAccessor, OnInit { - @Input() description = '' - truncatedDescriptionHTML = '' - descriptionHTML = '' - - private descriptionChanged = new Subject() - - constructor (private markdownService: MarkdownService) {} - - ngOnInit () { - this.descriptionChanged - .debounceTime(150) - .distinctUntilChanged() - .subscribe(() => this.updateDescriptionPreviews()) - - this.descriptionChanged.next(this.description) - } - - propagateChange = (_: any) => { /* empty */ } - - writeValue (description: string) { - this.description = description - - this.descriptionChanged.next(this.description) - } - - registerOnChange (fn: (_: any) => void) { - this.propagateChange = fn - } - - registerOnTouched () { - // Unused - } - - onModelChange () { - this.propagateChange(this.description) - - this.descriptionChanged.next(this.description) - } - - private updateDescriptionPreviews () { - this.truncatedDescriptionHTML = this.markdownService.markdownToHTML(truncate(this.description, { length: 250 })) - this.descriptionHTML = this.markdownService.markdownToHTML(this.description) - } -} diff --git a/client/src/sass/_mixins.scss b/client/src/sass/_mixins.scss index 121e16e10..d9c9e45ec 100644 --- a/client/src/sass/_mixins.scss +++ b/client/src/sass/_mixins.scss @@ -1,5 +1,5 @@ @mixin disable-default-a-behaviour { - &:hover, &:focus { + &:hover, &:focus, &:active { text-decoration: none !important; outline: none !important; } @@ -23,13 +23,15 @@ color: #fff; background-color: $orange-color; - &:hover, &:active, &:focus, &[disabled], &.disabled { + &:hover, &:active, &:focus { color: #fff; background-color: $orange-hoover-color; } &[disabled], &.disabled { cursor: default; + color: #fff; + background-color: #C6C6C6; } } diff --git a/client/src/sass/application.scss b/client/src/sass/application.scss index 0c999d659..3c5a00309 100644 --- a/client/src/sass/application.scss +++ b/client/src/sass/application.scss @@ -86,6 +86,10 @@ label { margin-top: 30px; margin-bottom: 25px; } + + &:hover, &:active, &:focus { + color: #000; +} } // On small screen, menu is absolute and displayed over the page -- cgit v1.2.3