aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/shared/forms
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/shared/forms')
-rw-r--r--client/src/app/shared/forms/form-validators/custom-config.ts7
-rw-r--r--client/src/app/shared/forms/markdown-textarea.component.html12
-rw-r--r--client/src/app/shared/forms/markdown-textarea.component.scss27
-rw-r--r--client/src/app/shared/forms/markdown-textarea.component.ts86
4 files changed, 132 insertions, 0 deletions
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 @@
1import { Validators } from '@angular/forms' 1import { Validators } from '@angular/forms'
2 2
3export const INSTANCE_NAME = {
4 VALIDATORS: [ Validators.required ],
5 MESSAGES: {
6 'required': 'Instance name is required.',
7 }
8}
9
3export const CACHE_PREVIEWS_SIZE = { 10export const CACHE_PREVIEWS_SIZE = {
4 VALIDATORS: [ Validators.required, Validators.min(1), Validators.pattern('[0-9]+') ], 11 VALIDATORS: [ Validators.required, Validators.min(1), Validators.pattern('[0-9]+') ],
5 MESSAGES: { 12 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 @@
1<div class="root" [ngStyle]="{ 'flex-direction': flexDirection }">
2 <textarea
3 [(ngModel)]="description" (ngModelChange)="onModelChange()"
4 [ngClass]="classes" [ngStyle]="{ width: textareaWidth, height: textareaHeight, 'margin-right': textareaMarginRight }"
5 id="description" name="description">
6 </textarea>
7
8 <tabset *ngIf="arePreviewsDisplayed()" #staticTabs class="previews">
9 <tab *ngIf="truncate !== undefined" heading="Truncated description preview" [innerHTML]="truncatedDescriptionHTML"></tab>
10 <tab heading="Complete description preview" [innerHTML]="descriptionHTML"></tab>
11 </tabset>
12</div>
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 @@
1@import '_variables';
2@import '_mixins';
3
4.root {
5 display: flex;
6
7 textarea {
8 @include peertube-textarea(100%, 150px);
9
10 margin-bottom: 15px;
11 }
12
13 /deep/ {
14 .nav-link {
15 display: flex !important;
16 align-items: center;
17 height: 30px !important;
18 padding: 0 15px !important;
19 }
20
21 .tab-content {
22 min-height: 75px;
23 padding: 15px;
24 font-size: 15px;
25 }
26 }
27}
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 @@
1import { Component, forwardRef, Input, OnInit } from '@angular/core'
2import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
3import 'rxjs/add/operator/debounceTime'
4import 'rxjs/add/operator/distinctUntilChanged'
5import { isInMobileView } from '@app/shared/misc/utils'
6import { MarkdownService } from '@app/videos/shared'
7import { Subject } from 'rxjs/Subject'
8import truncate from 'lodash-es/truncate'
9
10@Component({
11 selector: 'my-markdown-textarea',
12 templateUrl: './markdown-textarea.component.html',
13 styleUrls: [ './markdown-textarea.component.scss' ],
14 providers: [
15 {
16 provide: NG_VALUE_ACCESSOR,
17 useExisting: forwardRef(() => MarkdownTextareaComponent),
18 multi: true
19 }
20 ]
21})
22
23export class MarkdownTextareaComponent implements ControlValueAccessor, OnInit {
24 @Input() description = ''
25 @Input() classes: string[] = []
26 @Input() textareaWidth = '100%'
27 @Input() textareaHeight = '150px'
28 @Input() previewColumn = false
29 @Input() truncate: number
30
31 textareaMarginRight = '0'
32 flexDirection = 'column'
33 truncatedDescriptionHTML = ''
34 descriptionHTML = ''
35
36 private descriptionChanged = new Subject<string>()
37
38 constructor (private markdownService: MarkdownService) {}
39
40 ngOnInit () {
41 this.descriptionChanged
42 .debounceTime(150)
43 .distinctUntilChanged()
44 .subscribe(() => this.updateDescriptionPreviews())
45
46 this.descriptionChanged.next(this.description)
47
48 if (this.previewColumn) {
49 this.flexDirection = 'row'
50 this.textareaMarginRight = '15px'
51 }
52 }
53
54 propagateChange = (_: any) => { /* empty */ }
55
56 writeValue (description: string) {
57 this.description = description
58
59 this.descriptionChanged.next(this.description)
60 }
61
62 registerOnChange (fn: (_: any) => void) {
63 this.propagateChange = fn
64 }
65
66 registerOnTouched () {
67 // Unused
68 }
69
70 onModelChange () {
71 this.propagateChange(this.description)
72
73 this.descriptionChanged.next(this.description)
74 }
75
76 arePreviewsDisplayed () {
77 return isInMobileView() === false
78 }
79
80 private updateDescriptionPreviews () {
81 if (this.description === null || this.description === undefined) return
82
83 this.truncatedDescriptionHTML = this.markdownService.markdownToHTML(truncate(this.description, { length: this.truncate }))
84 this.descriptionHTML = this.markdownService.markdownToHTML(this.description)
85 }
86}