aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app')
-rw-r--r--client/src/app/+manage/video-channel-edit/video-channel-edit.component.html8
-rw-r--r--client/src/app/shared/shared-forms/markdown-textarea.component.html19
-rw-r--r--client/src/app/shared/shared-forms/markdown-textarea.component.scss317
-rw-r--r--client/src/app/shared/shared-forms/markdown-textarea.component.ts3
4 files changed, 131 insertions, 216 deletions
diff --git a/client/src/app/+manage/video-channel-edit/video-channel-edit.component.html b/client/src/app/+manage/video-channel-edit/video-channel-edit.component.html
index f71f73fec..420881f5a 100644
--- a/client/src/app/+manage/video-channel-edit/video-channel-edit.component.html
+++ b/client/src/app/+manage/video-channel-edit/video-channel-edit.component.html
@@ -66,13 +66,11 @@
66 helpType="markdownEnhanced" i18n-preHtml preHtml="Short text to tell people how they can support the channel (membership platform...).<br /><br /> 66 helpType="markdownEnhanced" i18n-preHtml preHtml="Short text to tell people how they can support the channel (membership platform...).<br /><br />
67 When a video is uploaded in this channel, the video support field will be automatically filled by this text." 67 When a video is uploaded in this channel, the video support field will be automatically filled by this text."
68 ></my-help> 68 ></my-help>
69
69 <my-markdown-textarea 70 <my-markdown-textarea
70 id="support" formControlName="support" textareaMaxWidth="500px" markdownType="enhanced" 71 id="support" formControlName="support" textareaMaxWidth="500px" markdownType="enhanced"
71 [classes]="{ 'input-error': formErrors['support'] }" 72 [formError]="formErrors['support']"
72 ></my-markdown-textarea> 73 ></my-markdown-textarea>
73 <div *ngIf="formErrors.support" class="form-error">
74 {{ formErrors.support }}
75 </div>
76 </div> 74 </div>
77 75
78 <div class="form-group" *ngIf="isBulkUpdateVideosDisplayed()"> 76 <div class="form-group" *ngIf="isBulkUpdateVideosDisplayed()">
diff --git a/client/src/app/shared/shared-forms/markdown-textarea.component.html b/client/src/app/shared/shared-forms/markdown-textarea.component.html
index 7c2a42791..afb046c7f 100644
--- a/client/src/app/shared/shared-forms/markdown-textarea.component.html
+++ b/client/src/app/shared/shared-forms/markdown-textarea.component.html
@@ -1,7 +1,8 @@
1<div class="root" [ngClass]="{ 'maximized': isMaximized }" [ngStyle]="{ 'max-width': textareaMaxWidth }"> 1<div class="root" [ngClass]="{ 'maximized': isMaximized }" [ngStyle]="{ 'max-width': textareaMaxWidth }">
2
2 <textarea #textarea 3 <textarea #textarea
3 [(ngModel)]="content" (ngModelChange)="onModelChange()" 4 [(ngModel)]="content" (ngModelChange)="onModelChange()"
4 class="form-control" [ngClass]="classes" 5 class="form-control" [ngClass]="{ 'input-error': formError }"
5 [attr.disabled]="disabled || null" 6 [attr.disabled]="disabled || null"
6 [ngStyle]="{ height: textareaHeight }" 7 [ngStyle]="{ height: textareaHeight }"
7 [id]="name" [name]="name"> 8 [id]="name" [name]="name">
@@ -25,14 +26,18 @@
25 </ng-template> 26 </ng-template>
26 </ng-container> 27 </ng-container>
27 28
28 <my-button 29 <my-global-icon
29 *ngIf="!isMaximized" [title]="maximizeInText" className="maximize-button" icon="fullscreen" (click)="onMaximizeClick()" [disabled]="disabled" 30 *ngIf="!isMaximized" role="button" [ngbTooltip]="maximizeInText"
30 ></my-button> 31 class="maximize-button" iconName="fullscreen" (click)="onMaximizeClick()" [ngClass]="{ disabled: disabled }"
32 ></my-global-icon>
31 33
32 <my-button 34 <my-global-icon
33 *ngIf="isMaximized" [title]="maximizeOutText" className="maximize-button" icon="exit-fullscreen" (click)="onMaximizeClick()" [disabled]="disabled" 35 *ngIf="isMaximized" role="button" [ngbTooltip]="maximizeOutText"
34 ></my-button> 36 class="maximize-button" iconName="exit-fullscreen" (click)="onMaximizeClick()" [ngClass]="{ disabled: disabled }"
37 ></my-global-icon>
35 </div> 38 </div>
36 39
37 <div [ngbNavOutlet]="nav"></div> 40 <div [ngbNavOutlet]="nav"></div>
41
42 <div *ngIf="!isMaximized && formError" class="form-error">{{ formError }}</div>
38</div> 43</div>
diff --git a/client/src/app/shared/shared-forms/markdown-textarea.component.scss b/client/src/app/shared/shared-forms/markdown-textarea.component.scss
index 116630d8a..c68c2c241 100644
--- a/client/src/app/shared/shared-forms/markdown-textarea.component.scss
+++ b/client/src/app/shared/shared-forms/markdown-textarea.component.scss
@@ -6,260 +6,169 @@ $nav-preview-tab-height: 30px;
6$base-padding: 15px; 6$base-padding: 15px;
7$input-border-radius: 3px; 7$input-border-radius: 3px;
8 8
9@mixin in-small-view { 9.root {
10 .root { 10 display: flex;
11 display: flex; 11 flex-direction: column;
12 flex-direction: column;
13 12
14 textarea { 13 textarea {
15 @include peertube-textarea(100%, 150px); 14 @include peertube-textarea(100%, 150px);
16 15
17 background-color: pvar(--markdownTextareaBackgroundColor); 16 background-color: pvar(--markdownTextareaBackgroundColor);
18 17
19 font-family: monospace; 18 font-family: monospace;
20 font-size: 13px; 19 font-size: 13px;
21 border-bottom: 0; 20 border-bottom: 0;
22 border-bottom-left-radius: unset; 21 border-bottom-left-radius: 0;
23 border-bottom-right-radius: unset; 22 border-bottom-right-radius: 0;
24 } 23 }
25 24
26 .nav-preview { 25 .nav-preview {
27 @include padding-left(10px); 26 padding: 10px;
28 @include padding-right(10px);
29 27
30 display: block; 28 border: 1px solid $input-border-color;
31 text-align: end; 29 border-top: 1px dashed $input-border-color;
32 padding-top: 10px;
33 padding-bottom: 10px;
34 border-top: 1px dashed $input-border-color;
35 border-left: 1px solid $input-border-color;
36 border-right: 1px solid $input-border-color;
37 border-bottom: 1px solid $input-border-color;
38 border-bottom-right-radius: $input-border-radius;
39
40 border-bottom-left-radius: $input-border-radius;
41 ::ng-deep {
42 .nav-link {
43 display: none !important;
44 }
45 30
46 .maximize-button { 31 border-bottom-right-radius: $input-border-radius;
47 padding: 0 7px; 32 border-bottom-left-radius: $input-border-radius;
48 cursor: pointer;
49
50 svg {
51 stroke: var(--mainForegroundColor);
52 opacity: 0.7;
53 }
54
55 &:hover,
56 &:active {
57 svg {
58 opacity: 1;
59 }
60 }
61 }
62 }
63 }
64 33
65 ::ng-deep { 34 display: flex;
66 .tab-content { 35 flex-grow: 1;
67 display: none; 36 border-bottom-left-radius: unset;
68 } 37 border-bottom-right-radius: unset;
69 } 38 border-bottom: 2px solid pvar(--mainColor);
70 }
71}
72 39
73@mixin nav-preview-medium { 40 .maximize-button {
74 display: flex; 41 @include margin-left(15px);
75 flex-grow: 1;
76 border-bottom-left-radius: unset;
77 border-bottom-right-radius: unset;
78 border-bottom: 2px solid pvar(--mainColor);
79 42
80 :first-child { 43 opacity: 0.6;
81 @include margin-left(auto); 44 cursor: default;
82 }
83 45
84 ::ng-deep { 46 &:not(.disabled) {
85 .nav-link { 47 cursor: pointer;
86 display: flex !important;
87 align-items: center;
88 height: $nav-preview-tab-height !important;
89 padding: 0 15px !important;
90 font-size: 85% !important;
91 opacity: .7;
92 }
93 48
94 .maximize-button { 49 &:hover,
95 @include margin-left(5px); 50 &:active {
51 opacity: 1;
52 }
53 }
96 } 54 }
97 } 55 }
98}
99 56
100@mixin content-preview-base { 57 .nav-pills {
101 display: block; 58 display: flex;
102 min-height: 75px; 59 align-items: center;
103 padding: $base-padding; 60 justify-content: flex-end;
104 overflow-y: auto;
105 word-wrap: break-word;
106}
107 61
108@mixin maximized-base { 62 > * {
109 $nav-preview-vertical-padding: 40px; 63 font-size: 0.9em !important;
64 }
65 }
110 66
111 flex-direction: row; 67 .tab-content {
112 z-index: #{z(header) - 1}; 68 min-height: 75px;
113 position: fixed; 69 max-height: 210px;
114 top: $header-height; 70 padding: $base-padding;
115 left: $menu-width;
116 max-height: none !important;
117 max-width: none !important;
118 width: calc(100% - #{$menu-width});
119 height: calc(100vh - #{$header-height}) !important;
120 71
121 .nav-preview { 72 overflow-y: auto;
122 @include nav-preview-medium(); 73 word-wrap: break-word;
123 @include padding-right(0);
124 @include padding-left(0);
125 74
126 padding-top: math.div($nav-preview-vertical-padding, 2); 75 border: 1px solid $input-border-color;
127 padding-bottom: math.div($nav-preview-vertical-padding, 2);
128 position: absolute;
129 background-color: pvar(--mainBackgroundColor);
130 width: 100% !important;
131 border-top: 0; 76 border-top: 0;
132 border-left: 0;
133 border-right: 0;
134 77
135 :last-child { 78 border-bottom-left-radius: $input-border-radius;
136 @include margin-right(pvar(--horizontalMarginContent)); 79 border-bottom-right-radius: $input-border-radius;
137 }
138 } 80 }
139 81
140 ::ng-deep .tab-content { 82 &.maximized {
141 @include content-preview-base(); 83 z-index: #{z(header) - 1};
142 background-color: pvar(--mainBackgroundColor); 84 position: fixed;
143 scrollbar-color: pvar(--actionButtonColor) pvar(--mainBackgroundColor); 85 top: $header-height;
144 } 86 left: $menu-width;
145 87
146 textarea,
147 ::ng-deep .tab-content {
148 max-height: none !important; 88 max-height: none !important;
149 max-width: none !important; 89 max-width: none !important;
150 margin-top: #{$nav-preview-tab-height + $nav-preview-vertical-padding} !important; 90 width: calc(100% - #{$menu-width});
151 height: calc(100vh - #{$header-height + $nav-preview-tab-height + $nav-preview-vertical-padding}) !important; 91 height: calc(100vh - #{$header-height});
152 width: 50% !important;
153 border: 0 !important;
154 border-radius: unset !important;
155 }
156
157 :host-context(.expanded) {
158 .root.maximized {
159 left: 0;
160 width: 100%;
161 }
162 }
163}
164 92
165@mixin maximized-in-small-view { 93 display: grid;
166 .root.maximized { 94 grid-template-rows: auto 1fr;
167 @include maximized-base(); 95 grid-template-columns: 1fr 1fr;
168 96
169 textarea { 97 background-color: pvar(--mainBackgroundColor);
170 display: none;
171 }
172
173 ::ng-deep .tab-content {
174 width: 100% !important;
175 }
176 }
177}
178 98
179@mixin maximized-tabs-in-mobile-view {
180 // Ellipsis on tabs for mobile view
181 .root.maximized {
182 .nav-preview { 99 .nav-preview {
183 ::ng-deep .nav-link { 100 grid-row: 1;
184 @include ellipsis(); 101 grid-column: 1 / 3;
185 @include margin-right(10px !important);
186 102
187 display: block !important; 103 border: 0;
188 max-width: 45% !important; 104 border-bottom: 2px solid pvar(--mainColor);
189 padding: 5px 0 !important;
190 text-align: center;
191 105
192 &:not(.active) { 106 padding: 20px 0;
193 max-width: 15% !important; 107 width: 100% !important;
194 }
195 108
196 &.active { 109 .maximize-button {
197 padding: 5px 15px !important; 110 @include margin-right(15px);
198 }
199 } 111 }
200 } 112 }
201 }
202}
203 113
204@mixin in-medium-view { 114 textarea {
205 .root { 115 grid-column: 1;
206 .nav-preview { 116
207 @include nav-preview-medium(); 117 border: 0;
118 border-right: 1px dashed $input-border-color;
119
120 resize: none;
208 } 121 }
209 122
210 ::ng-deep .tab-content { 123 ::ng-deep .tab-content {
211 @include content-preview-base(); 124 grid-column: 2;
212 max-height: 210px;
213 border-bottom: 1px solid $input-border-color;
214 border-left: 1px solid $input-border-color;
215 border-right: 1px solid $input-border-color;
216 border-bottom-left-radius: $input-border-radius;
217 border-bottom-right-radius: $input-border-radius;
218 }
219 }
220}
221 125
222@mixin maximized-in-medium-view { 126 border: 0;
223 .root.maximized {
224 @include maximized-base();
225 127
226 textarea {
227 display: block; 128 display: block;
228 padding: $base-padding; 129 overflow-y: auto;
229 border-right: 1px dashed $input-border-color !important; 130 word-wrap: break-word;
230 resize: none;
231 scrollbar-color: pvar(--actionButtonColor) pvar(--markdownTextareaBackgroundColor);
232 131
233 &:focus { 132 scrollbar-color: pvar(--actionButtonColor) pvar(--mainBackgroundColor);
234 box-shadow: none;
235 }
236 } 133 }
237 }
238}
239 134
240@include in-small-view(); 135 textarea,
241@include maximized-in-small-view(); 136 ::ng-deep .tab-content {
137 grid-row: 2;
242 138
243@media only screen and (max-width: $mobile-view) { 139 height: 100% !important;
244 @include maximized-tabs-in-mobile-view(); 140 max-height: none !important;
245} 141 border-radius: 0;
246 142
247@media only screen and (max-width: #{$mobile-view + $menu-width}) { 143 padding: 15px;
248 :host-context(.main-col:not(.expanded)) { 144 }
249 @include maximized-tabs-in-mobile-view(); 145
250 } 146 @media screen and (max-width: $mobile-view) {
251} 147 grid-template-rows: auto 45% 1fr;
148 grid-template-columns: 1fr;
149
150 .nav-preview {
151 grid-column: 1;
152 }
252 153
253@media only screen and (min-width: $small-view) { 154 textarea {
254 @include maximized-in-medium-view(); 155 grid-row: 2;
156 grid-column: 1;
157 border: 0;
158 border-bottom: 1px dashed $input-border-color;;
159 }
255 160
256 :host-context(.expanded) { 161 ::ng-deep .tab-content {
257 @include in-medium-view(); 162 grid-column: 1;
163 grid-row: 3;
164 }
165 }
258 } 166 }
259} 167}
260 168
261@media only screen and (min-width: #{$small-view + $menu-width}) { 169:host-context(.main-col.expanded) {
262 :host-context(.main-col:not(.expanded)) { 170 .root.maximized {
263 @include in-medium-view(); 171 left: 0;
172 width: 100%;
264 } 173 }
265} 174}
diff --git a/client/src/app/shared/shared-forms/markdown-textarea.component.ts b/client/src/app/shared/shared-forms/markdown-textarea.component.ts
index dcb5d20da..5a603c157 100644
--- a/client/src/app/shared/shared-forms/markdown-textarea.component.ts
+++ b/client/src/app/shared/shared-forms/markdown-textarea.component.ts
@@ -24,6 +24,7 @@ import { Video } from '@shared/models'
24export class MarkdownTextareaComponent implements ControlValueAccessor, OnInit { 24export class MarkdownTextareaComponent implements ControlValueAccessor, OnInit {
25 @Input() content = '' 25 @Input() content = ''
26 26
27 @Input() formError: string
27 @Input() classes: string[] | { [klass: string]: any[] | any } = [] 28 @Input() classes: string[] | { [klass: string]: any[] | any } = []
28 29
29 @Input() textareaMaxWidth = '100%' 30 @Input() textareaMaxWidth = '100%'
@@ -93,6 +94,8 @@ export class MarkdownTextareaComponent implements ControlValueAccessor, OnInit {
93 } 94 }
94 95
95 onMaximizeClick () { 96 onMaximizeClick () {
97 if (this.disabled) return
98
96 this.isMaximized = !this.isMaximized 99 this.isMaximized = !this.isMaximized
97 100
98 // Make sure textarea have the focus 101 // Make sure textarea have the focus