From 2de96f4d6b800076743ed2073f9529816cfd5c8a Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 30 Oct 2017 20:26:06 +0100 Subject: Lazy description and previews to video form --- .../videos/+video-edit/video-add.component.html | 8 +-- .../app/videos/+video-edit/video-add.component.ts | 20 +++++-- .../src/app/videos/+video-edit/video-add.module.ts | 11 +--- .../app/videos/+video-edit/video-edit.module.ts | 33 +++++++++++ .../videos/+video-edit/video-update.component.html | 9 +-- .../videos/+video-edit/video-update.component.ts | 33 +++++++---- .../app/videos/+video-edit/video-update.module.ts | 11 +--- .../+video-watch/video-report.component.html | 2 +- .../videos/+video-watch/video-watch.component.html | 10 ++++ .../videos/+video-watch/video-watch.component.scss | 12 ++++ .../videos/+video-watch/video-watch.component.ts | 45 +++++++++++++- client/src/app/videos/shared/index.ts | 1 + .../videos/shared/video-description.component.html | 9 +++ .../videos/shared/video-description.component.scss | 15 +++++ .../videos/shared/video-description.component.ts | 68 ++++++++++++++++++++++ .../src/app/videos/shared/video-details.model.ts | 2 + client/src/app/videos/shared/video.service.ts | 14 ++--- 17 files changed, 248 insertions(+), 55 deletions(-) create mode 100644 client/src/app/videos/+video-edit/video-edit.module.ts create mode 100644 client/src/app/videos/shared/video-description.component.html create mode 100644 client/src/app/videos/shared/video-description.component.scss create mode 100644 client/src/app/videos/shared/video-description.component.ts (limited to 'client/src/app/videos') 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 3bf4101f4..a70788ed8 100644 --- a/client/src/app/videos/+video-edit/video-add.component.html +++ b/client/src/app/videos/+video-edit/video-add.component.html @@ -28,7 +28,6 @@
@@ -103,11 +102,8 @@
- + +
{{ formErrors.description }}
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 92b03e8c9..5b5557ed9 100644 --- a/client/src/app/videos/+video-edit/video-add.component.ts +++ b/client/src/app/videos/+video-edit/video-add.component.ts @@ -82,7 +82,7 @@ export class VideoAddComponent extends FormReactive implements OnInit { category: [ '', VIDEO_CATEGORY.VALIDATORS ], licence: [ '', VIDEO_LICENCE.VALIDATORS ], language: [ '', VIDEO_LANGUAGE.VALIDATORS ], - channelId: [ this.userVideoChannels[0].id, VIDEO_CHANNEL.VALIDATORS ], + channelId: [ '', VIDEO_CHANNEL.VALIDATORS ], description: [ '', VIDEO_DESCRIPTION.VALIDATORS ], videofile: [ '', VIDEO_FILE.VALIDATORS ], tags: [ '' ] @@ -96,10 +96,22 @@ export class VideoAddComponent extends FormReactive implements OnInit { this.videoLicences = this.serverService.getVideoLicences() this.videoLanguages = this.serverService.getVideoLanguages() - const user = this.authService.getUser() - this.userVideoChannels = user.videoChannels.map(v => ({ id: v.id, label: v.name })) - this.buildForm() + + this.authService.userInformationLoaded + .subscribe( + () => { + const user = this.authService.getUser() + if (!user) return + + const videoChannels = user.videoChannels + 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 }) + } + ) } // The goal is to keep reactive form validation (required field) diff --git a/client/src/app/videos/+video-edit/video-add.module.ts b/client/src/app/videos/+video-edit/video-add.module.ts index 141d33ad2..3d937b008 100644 --- a/client/src/app/videos/+video-edit/video-add.module.ts +++ b/client/src/app/videos/+video-edit/video-add.module.ts @@ -1,17 +1,14 @@ import { NgModule } from '@angular/core' -import { TagInputModule } from 'ngx-chips' - import { VideoAddRoutingModule } from './video-add-routing.module' import { VideoAddComponent } from './video-add.component' -import { VideoService } from '../shared' +import { VideoEditModule } from './video-edit.module' import { SharedModule } from '../../shared' @NgModule({ imports: [ - TagInputModule, - VideoAddRoutingModule, + VideoEditModule, SharedModule ], @@ -23,8 +20,6 @@ import { SharedModule } from '../../shared' VideoAddComponent ], - providers: [ - VideoService - ] + providers: [ ] }) export class VideoAddModule { } diff --git a/client/src/app/videos/+video-edit/video-edit.module.ts b/client/src/app/videos/+video-edit/video-edit.module.ts new file mode 100644 index 000000000..33f654960 --- /dev/null +++ b/client/src/app/videos/+video-edit/video-edit.module.ts @@ -0,0 +1,33 @@ +import { NgModule } from '@angular/core' + +import { TagInputModule } from 'ngx-chips' +import { TabsModule } from 'ngx-bootstrap/tabs' + +import { VideoService, MarkdownService, VideoDescriptionComponent } from '../shared' +import { SharedModule } from '../../shared' + +@NgModule({ + imports: [ + TagInputModule, + TabsModule.forRoot(), + + SharedModule + ], + + declarations: [ + VideoDescriptionComponent + ], + + exports: [ + TagInputModule, + TabsModule, + + VideoDescriptionComponent + ], + + providers: [ + VideoService, + MarkdownService + ] +}) +export class VideoEditModule { } 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 4dcb3ea56..ec040630e 100644 --- a/client/src/app/videos/+video-edit/video-update.component.html +++ b/client/src/app/videos/+video-edit/video-update.component.html @@ -62,7 +62,7 @@
- (press enter to add the tag) + (press enter to add the tag) - + +
{{ formErrors.description }}
diff --git a/client/src/app/videos/+video-edit/video-update.component.ts b/client/src/app/videos/+video-edit/video-update.component.ts index 30390ac05..6ced77f1a 100644 --- a/client/src/app/videos/+video-edit/video-update.component.ts +++ b/client/src/app/videos/+video-edit/video-update.component.ts @@ -1,6 +1,8 @@ import { Component, OnInit } from '@angular/core' import { FormBuilder, FormGroup } from '@angular/forms' import { ActivatedRoute, Router } from '@angular/router' +import { Observable } from 'rxjs/Observable' +import 'rxjs/add/observable/forkJoin' import { NotificationsService } from 'angular2-notifications' @@ -84,19 +86,26 @@ export class VideoUpdateComponent extends FormReactive implements OnInit { this.videoLanguages = this.serverService.getVideoLanguages() const uuid: string = this.route.snapshot.params['uuid'] - this.videoService.getVideo(uuid) - .subscribe( - video => { - this.video = new VideoEdit(video) - - this.hydrateFormFromVideo() - }, - err => { - console.error(err) - this.error = 'Cannot fetch video.' - } - ) + this.videoService.getVideo(uuid) + .switchMap(video => { + return this.videoService + .loadCompleteDescription(video.descriptionPath) + .do(description => video.description = description) + .map(() => video) + }) + .subscribe( + video => { + this.video = new VideoEdit(video) + + this.hydrateFormFromVideo() + }, + + err => { + console.error(err) + this.error = 'Cannot fetch video.' + } + ) } checkForm () { diff --git a/client/src/app/videos/+video-edit/video-update.module.ts b/client/src/app/videos/+video-edit/video-update.module.ts index eeb2e35e2..f7bd77c75 100644 --- a/client/src/app/videos/+video-edit/video-update.module.ts +++ b/client/src/app/videos/+video-edit/video-update.module.ts @@ -1,17 +1,14 @@ import { NgModule } from '@angular/core' -import { TagInputModule } from 'ngx-chips' - import { VideoUpdateRoutingModule } from './video-update-routing.module' import { VideoUpdateComponent } from './video-update.component' -import { VideoService } from '../shared' +import { VideoEditModule } from './video-edit.module' import { SharedModule } from '../../shared' @NgModule({ imports: [ - TagInputModule, - VideoUpdateRoutingModule, + VideoEditModule, SharedModule ], @@ -23,8 +20,6 @@ import { SharedModule } from '../../shared' VideoUpdateComponent ], - providers: [ - VideoService - ] + providers: [ ] }) export class VideoUpdateModule { } diff --git a/client/src/app/videos/+video-watch/video-report.component.html b/client/src/app/videos/+video-watch/video-report.component.html index 741080ead..ceb7cf50a 100644 --- a/client/src/app/videos/+video-watch/video-report.component.html +++ b/client/src/app/videos/+video-watch/video-report.component.html @@ -13,7 +13,7 @@
- + + + + + + diff --git a/client/src/app/videos/shared/video-description.component.scss b/client/src/app/videos/shared/video-description.component.scss new file mode 100644 index 000000000..d8d73e846 --- /dev/null +++ b/client/src/app/videos/shared/video-description.component.scss @@ -0,0 +1,15 @@ +textarea { + height: 150px; +} + +.previews /deep/ { + .nav { + margin-top: 10px; + font-size: 0.9em; + } + + .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 new file mode 100644 index 000000000..d9ffb7800 --- /dev/null +++ b/client/src/app/videos/shared/video-description.component.ts @@ -0,0 +1,68 @@ +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/app/videos/shared/video-details.model.ts b/client/src/app/videos/shared/video-details.model.ts index 3a6ecc480..68ded5210 100644 --- a/client/src/app/videos/shared/video-details.model.ts +++ b/client/src/app/videos/shared/video-details.model.ts @@ -38,12 +38,14 @@ export class VideoDetails extends Video implements VideoDetailsServerModel { likes: number dislikes: number nsfw: boolean + descriptionPath: string files: VideoFile[] channel: VideoChannel constructor (hash: VideoDetailsServerModel) { super(hash) + this.descriptionPath = hash.descriptionPath this.files = hash.files this.channel = hash.channel } diff --git a/client/src/app/videos/shared/video.service.ts b/client/src/app/videos/shared/video.service.ts index 8fdc1f213..7d5372334 100644 --- a/client/src/app/videos/shared/video.service.ts +++ b/client/src/app/videos/shared/video.service.ts @@ -99,15 +99,11 @@ export class VideoService { .catch((res) => this.restExtractor.handleError(res)) } - reportVideo (id: number, reason: string) { - const url = VideoService.BASE_VIDEO_URL + id + '/abuse' - const body: VideoAbuseCreate = { - reason - } - - return this.authHttp.post(url, body) - .map(this.restExtractor.extractDataBool) - .catch(res => this.restExtractor.handleError(res)) + loadCompleteDescription (descriptionPath: string) { + return this.authHttp + .get(API_URL + descriptionPath) + .map(res => res['description']) + .catch((res) => this.restExtractor.handleError(res)) } setVideoLike (id: number) { -- cgit v1.2.3