From 66b16cafb380012d3eca14e524d86f2450e04069 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 31 Jan 2018 16:42:40 +0100 Subject: Add new name/terms/description config options --- .../edit-custom-config.component.html | 35 +++++++++ .../edit-custom-config.component.ts | 25 ++++++- .../shared/forms/form-validators/custom-config.ts | 7 ++ .../shared/forms/markdown-textarea.component.html | 12 +++ .../shared/forms/markdown-textarea.component.scss | 27 +++++++ .../shared/forms/markdown-textarea.component.ts | 86 ++++++++++++++++++++++ client/src/app/shared/shared.module.ts | 13 +++- client/src/app/shared/video/video.service.ts | 8 +- .../shared/video-description.component.html | 9 --- .../shared/video-description.component.scss | 24 ------ .../shared/video-description.component.ts | 73 ------------------ .../+video-edit/shared/video-edit.component.html | 6 +- .../videos/+video-edit/shared/video-edit.module.ts | 13 +--- client/src/app/videos/shared/markdown.service.ts | 18 +++-- 14 files changed, 221 insertions(+), 135 deletions(-) create mode 100644 client/src/app/shared/forms/markdown-textarea.component.html create mode 100644 client/src/app/shared/forms/markdown-textarea.component.scss create mode 100644 client/src/app/shared/forms/markdown-textarea.component.ts delete mode 100644 client/src/app/videos/+video-edit/shared/video-description.component.html delete mode 100644 client/src/app/videos/+video-edit/shared/video-description.component.scss delete mode 100644 client/src/app/videos/+video-edit/shared/video-description.component.ts (limited to 'client/src/app') diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html index c568a43b4..0fe2aa203 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html +++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html @@ -2,6 +2,41 @@
+
Instance
+ +
+ + +
+ {{ formErrors.instanceName }} +
+
+ +
+ + +
+ {{ formErrors.instanceDescription }} +
+
+ +
+ + +
+ {{ formErrors.instanceTerms }} +
+
+
Cache
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts index 1b3522786..cd8c926f7 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts +++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts @@ -4,7 +4,13 @@ import { Router } from '@angular/router' import { ConfigService } from '@app/+admin/config/shared/config.service' import { ServerService } from '@app/core/server/server.service' import { FormReactive, USER_VIDEO_QUOTA } from '@app/shared' -import { ADMIN_EMAIL, CACHE_PREVIEWS_SIZE, SIGNUP_LIMIT, TRANSCODING_THREADS } from '@app/shared/forms/form-validators/custom-config' +import { + ADMIN_EMAIL, + CACHE_PREVIEWS_SIZE, + INSTANCE_NAME, + SIGNUP_LIMIT, + TRANSCODING_THREADS +} from '@app/shared/forms/form-validators/custom-config' import { NotificationsService } from 'angular2-notifications' import { CustomConfig } from '../../../../../../shared/models/config/custom-config.model' @@ -36,6 +42,9 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit { form: FormGroup formErrors = { + instanceName: '', + instanceDescription: '', + instanceTerms: '', cachePreviewsSize: '', signupLimit: '', adminEmail: '', @@ -43,6 +52,7 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit { transcodingThreads: '' } validationMessages = { + instanceName: INSTANCE_NAME.MESSAGES, cachePreviewsSize: CACHE_PREVIEWS_SIZE.MESSAGES, signupLimit: SIGNUP_LIMIT.MESSAGES, adminEmail: ADMIN_EMAIL.MESSAGES, @@ -65,6 +75,9 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit { buildForm () { const formGroupData = { + instanceName: [ '', INSTANCE_NAME.VALIDATORS ], + instanceDescription: [ '' ], + instanceTerms: [ '' ], cachePreviewsSize: [ '', CACHE_PREVIEWS_SIZE.VALIDATORS ], signupEnabled: [ ], signupLimit: [ '', SIGNUP_LIMIT.VALIDATORS ], @@ -109,6 +122,11 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit { formValidated () { const data = { + instance: { + name: this.form.value['instanceName'], + description: this.form.value['instanceDescription'], + terms: this.form.value['instanceTerms'] + }, cache: { previews: { size: this.form.value['cachePreviewsSize'] @@ -146,6 +164,8 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit { this.serverService.loadConfig() this.updateForm() + + this.notificationsService.success('Success', 'Configuration updated.') }, err => this.notificationsService.error('Error', err.message) @@ -154,6 +174,9 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit { private updateForm () { const data = { + instanceName: this.customConfig.instance.name, + instanceDescription: this.customConfig.instance.description, + instanceTerms: this.customConfig.instance.terms, cachePreviewsSize: this.customConfig.cache.previews.size, signupEnabled: this.customConfig.signup.enabled, signupLimit: this.customConfig.signup.limit, diff --git a/client/src/app/shared/forms/form-validators/custom-config.ts b/client/src/app/shared/forms/form-validators/custom-config.ts index 17ae0e75c..9e3fa98d8 100644 --- a/client/src/app/shared/forms/form-validators/custom-config.ts +++ b/client/src/app/shared/forms/form-validators/custom-config.ts @@ -1,5 +1,12 @@ import { Validators } from '@angular/forms' +export const INSTANCE_NAME = { + VALIDATORS: [ Validators.required ], + MESSAGES: { + 'required': 'Instance name is required.', + } +} + export const CACHE_PREVIEWS_SIZE = { VALIDATORS: [ Validators.required, Validators.min(1), Validators.pattern('[0-9]+') ], MESSAGES: { diff --git a/client/src/app/shared/forms/markdown-textarea.component.html b/client/src/app/shared/forms/markdown-textarea.component.html new file mode 100644 index 000000000..d2d4cf95c --- /dev/null +++ b/client/src/app/shared/forms/markdown-textarea.component.html @@ -0,0 +1,12 @@ +
+ + + + + + +
diff --git a/client/src/app/shared/forms/markdown-textarea.component.scss b/client/src/app/shared/forms/markdown-textarea.component.scss new file mode 100644 index 000000000..82aff541d --- /dev/null +++ b/client/src/app/shared/forms/markdown-textarea.component.scss @@ -0,0 +1,27 @@ +@import '_variables'; +@import '_mixins'; + +.root { + display: flex; + + textarea { + @include peertube-textarea(100%, 150px); + + margin-bottom: 15px; + } + + /deep/ { + .nav-link { + display: flex !important; + align-items: center; + height: 30px !important; + padding: 0 15px !important; + } + + .tab-content { + min-height: 75px; + padding: 15px; + font-size: 15px; + } + } +} diff --git a/client/src/app/shared/forms/markdown-textarea.component.ts b/client/src/app/shared/forms/markdown-textarea.component.ts new file mode 100644 index 000000000..20f13b28c --- /dev/null +++ b/client/src/app/shared/forms/markdown-textarea.component.ts @@ -0,0 +1,86 @@ +import { Component, forwardRef, Input, OnInit } from '@angular/core' +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' +import 'rxjs/add/operator/debounceTime' +import 'rxjs/add/operator/distinctUntilChanged' +import { isInMobileView } from '@app/shared/misc/utils' +import { MarkdownService } from '@app/videos/shared' +import { Subject } from 'rxjs/Subject' +import truncate from 'lodash-es/truncate' + +@Component({ + selector: 'my-markdown-textarea', + templateUrl: './markdown-textarea.component.html', + styleUrls: [ './markdown-textarea.component.scss' ], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => MarkdownTextareaComponent), + multi: true + } + ] +}) + +export class MarkdownTextareaComponent implements ControlValueAccessor, OnInit { + @Input() description = '' + @Input() classes: string[] = [] + @Input() textareaWidth = '100%' + @Input() textareaHeight = '150px' + @Input() previewColumn = false + @Input() truncate: number + + textareaMarginRight = '0' + flexDirection = 'column' + truncatedDescriptionHTML = '' + descriptionHTML = '' + + private descriptionChanged = new Subject() + + constructor (private markdownService: MarkdownService) {} + + ngOnInit () { + this.descriptionChanged + .debounceTime(150) + .distinctUntilChanged() + .subscribe(() => this.updateDescriptionPreviews()) + + this.descriptionChanged.next(this.description) + + if (this.previewColumn) { + this.flexDirection = 'row' + this.textareaMarginRight = '15px' + } + } + + 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) + } + + arePreviewsDisplayed () { + return isInMobileView() === false + } + + private updateDescriptionPreviews () { + if (this.description === null || this.description === undefined) return + + this.truncatedDescriptionHTML = this.markdownService.markdownToHTML(truncate(this.description, { length: this.truncate })) + this.descriptionHTML = this.markdownService.markdownToHTML(this.description) + } +} diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts index a5c56cb46..d8f98bdf6 100644 --- a/client/src/app/shared/shared.module.ts +++ b/client/src/app/shared/shared.module.ts @@ -3,10 +3,13 @@ import { HttpClientModule } from '@angular/common/http' import { NgModule } from '@angular/core' import { FormsModule, ReactiveFormsModule } from '@angular/forms' import { RouterModule } from '@angular/router' +import { MarkdownTextareaComponent } from '@app/shared/forms/markdown-textarea.component' +import { MarkdownService } from '@app/videos/shared' import { LoadingBarHttpClientModule } from '@ngx-loading-bar/http-client' import { BsDropdownModule } from 'ngx-bootstrap/dropdown' import { ModalModule } from 'ngx-bootstrap/modal' +import { TabsModule } from 'ngx-bootstrap/tabs' import { InfiniteScrollModule } from 'ngx-infinite-scroll' import { BytesPipe, KeysPipe, NgPipesModule } from 'ngx-pipes' import { SharedModule as PrimeSharedModule } from 'primeng/components/common/shared' @@ -40,7 +43,8 @@ import { VideoService } from './video/video.service' PrimeSharedModule, InfiniteScrollModule, - NgPipesModule + NgPipesModule, + TabsModule.forRoot() ], declarations: [ @@ -50,7 +54,8 @@ import { VideoService } from './video/video.service' DeleteButtonComponent, EditButtonComponent, NumberFormatterPipe, - FromNowPipe + FromNowPipe, + MarkdownTextareaComponent ], exports: [ @@ -74,6 +79,7 @@ import { VideoService } from './video/video.service' VideoMiniatureComponent, DeleteButtonComponent, EditButtonComponent, + MarkdownTextareaComponent, NumberFormatterPipe, FromNowPipe @@ -86,7 +92,8 @@ import { VideoService } from './video/video.service' VideoAbuseService, VideoBlacklistService, UserService, - VideoService + VideoService, + MarkdownService ] }) export class SharedModule { } diff --git a/client/src/app/shared/video/video.service.ts b/client/src/app/shared/video/video.service.ts index 50761ca0c..d4f5e258f 100644 --- a/client/src/app/shared/video/video.service.ts +++ b/client/src/app/shared/video/video.service.ts @@ -42,10 +42,10 @@ export class VideoService { } updateVideo (video: VideoEdit) { - const language = video.language || undefined - const licence = video.licence || undefined - const category = video.category || undefined - const description = video.description || undefined + const language = video.language || null + const licence = video.licence || null + const category = video.category || null + const description = video.description || null const body: VideoUpdate = { name: video.name, 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 deleted file mode 100644 index 989292c47..000000000 --- a/client/src/app/videos/+video-edit/shared/video-description.component.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - 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 deleted file mode 100644 index 2c731bee3..000000000 --- a/client/src/app/videos/+video-edit/shared/video-description.component.scss +++ /dev/null @@ -1,24 +0,0 @@ -@import '_variables'; -@import '_mixins'; - -textarea { - @include peertube-textarea(100%, 150px); - - margin-bottom: 15px; -} - -/deep/ { - .nav-link { - display: flex !important; - align-items: center; - height: 30px !important; - padding: 0 15px !important; - } - - .tab-content { - min-height: 75px; - padding: 15px; - font-size: 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 deleted file mode 100644 index eba345412..000000000 --- a/client/src/app/videos/+video-edit/shared/video-description.component.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { Component, forwardRef, Input, OnInit } from '@angular/core' -import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' -import 'rxjs/add/operator/debounceTime' -import 'rxjs/add/operator/distinctUntilChanged' -import { isInMobileView } from '@app/shared/misc/utils' -import { Subject } from 'rxjs/Subject' -import { MarkdownService } from '../../shared' -import truncate from 'lodash-es/truncate' - -@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) - } - - arePreviewsDisplayed () { - return isInMobileView() === false - } - - private updateDescriptionPreviews () { - if (!this.description) return - - 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.html b/client/src/app/videos/+video-edit/shared/video-edit.component.html index 80377933e..d031825bd 100644 --- a/client/src/app/videos/+video-edit/shared/video-edit.component.html +++ b/client/src/app/videos/+video-edit/shared/video-edit.component.html @@ -12,14 +12,14 @@
(press Enter to add)
- +
{{ formErrors.description }} 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 ce106d82f..098a71ae6 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 @@ -1,23 +1,17 @@ import { NgModule } from '@angular/core' - -import { TagInputModule } from 'ngx-chips' import { TabsModule } from 'ngx-bootstrap/tabs' - -import { MarkdownService } from '../../shared' +import { TagInputModule } from 'ngx-chips' import { SharedModule } from '../../../shared' -import { VideoDescriptionComponent } from './video-description.component' import { VideoEditComponent } from './video-edit.component' @NgModule({ imports: [ TagInputModule, - TabsModule.forRoot(), SharedModule ], declarations: [ - VideoDescriptionComponent, VideoEditComponent ], @@ -25,12 +19,9 @@ import { VideoEditComponent } from './video-edit.component' TagInputModule, TabsModule, - VideoDescriptionComponent, VideoEditComponent ], - providers: [ - MarkdownService - ] + providers: [] }) export class VideoEditModule { } diff --git a/client/src/app/videos/shared/markdown.service.ts b/client/src/app/videos/shared/markdown.service.ts index 82745f0c6..fd0330f9b 100644 --- a/client/src/app/videos/shared/markdown.service.ts +++ b/client/src/app/videos/shared/markdown.service.ts @@ -14,6 +14,17 @@ export class MarkdownService { .enable('link') .enable('newline') + this.setTargetToLinks() + } + + markdownToHTML (markdown: string) { + const html = this.markdownIt.render(markdown) + + // Avoid linkify truncated links + return html.replace(/]+>([^<]+)<\/a>\s*...(<\/p>)?$/mi, '$1...') + } + + private setTargetToLinks () { // Snippet from markdown-it documentation: https://github.com/markdown-it/markdown-it/blob/master/docs/architecture.md#renderer const defaultRender = this.markdownIt.renderer.rules.link_open || function (tokens, idx, options, env, self) { return self.renderToken(tokens, idx, options) @@ -33,11 +44,4 @@ export class MarkdownService { return defaultRender(tokens, idx, options, env, self) } } - - markdownToHTML (markdown: string) { - const html = this.markdownIt.render(markdown) - - // Avoid linkify truncated links - return html.replace(/]+>([^<]+)<\/a>\s*...(<\/p>)?$/mi, '$1...') - } } -- cgit v1.2.3