diff options
13 files changed, 208 insertions, 179 deletions
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 9991e1f63..bde27b206 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 | |||
@@ -1,9 +1,11 @@ | |||
1 | <form role="form" [formGroup]="form"> | 1 | <form role="form" [formGroup]="form"> |
2 | 2 | ||
3 | <ngb-tabset #tabs class="root-tabset bootstrap"> | 3 | <div ngbNav #nav="ngbNav" class="nav-tabs"> |
4 | 4 | ||
5 | <ngb-tab id="instance-information" i18n-title title="Instance information"> | 5 | <ng-container ngbNavItem="instance-information"> |
6 | <ng-template ngbTabContent> | 6 | <a ngbNavLink i18n>Instance information</a> |
7 | |||
8 | <ng-template ngbNavContent> | ||
7 | 9 | ||
8 | <ng-container formGroupName="instance"> | 10 | <ng-container formGroupName="instance"> |
9 | 11 | ||
@@ -225,10 +227,12 @@ | |||
225 | 227 | ||
226 | </ng-container> | 228 | </ng-container> |
227 | </ng-template> | 229 | </ng-template> |
228 | </ngb-tab> | 230 | </ng-container> |
231 | |||
232 | <ng-container ngbNavItem="basic-configuration"> | ||
233 | <a ngbNavLink i18n>Basic configuration</a> | ||
229 | 234 | ||
230 | <ngb-tab id="basic-configuration" i18n-title title="Basic configuration"> | 235 | <ng-template ngbNavContent> |
231 | <ng-template ngbTabContent> | ||
232 | 236 | ||
233 | <div class="form-row mt-5"> <!-- appearance grid --> | 237 | <div class="form-row mt-5"> <!-- appearance grid --> |
234 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 238 | <div class="form-group col-12 col-lg-4 col-xl-3"> |
@@ -348,7 +352,7 @@ | |||
348 | 352 | ||
349 | <ng-container formGroupName="import"> | 353 | <ng-container formGroupName="import"> |
350 | <ng-container formGroupName="videos"> | 354 | <ng-container formGroupName="videos"> |
351 | 355 | ||
352 | <div class="form-group" formGroupName="http"> | 356 | <div class="form-group" formGroupName="http"> |
353 | <my-peertube-checkbox | 357 | <my-peertube-checkbox |
354 | inputName="importVideosHttpEnabled" formControlName="enabled" | 358 | inputName="importVideosHttpEnabled" formControlName="enabled" |
@@ -369,7 +373,7 @@ | |||
369 | <ng-container formGroupName="autoBlacklist"> | 373 | <ng-container formGroupName="autoBlacklist"> |
370 | <ng-container formGroupName="videos"> | 374 | <ng-container formGroupName="videos"> |
371 | <ng-container formGroupName="ofUsers"> | 375 | <ng-container formGroupName="ofUsers"> |
372 | 376 | ||
373 | <div class="form-group"> | 377 | <div class="form-group"> |
374 | <my-peertube-checkbox | 378 | <my-peertube-checkbox |
375 | inputName="autoBlacklistVideosOfUsersEnabled" formControlName="enabled" | 379 | inputName="autoBlacklistVideosOfUsersEnabled" formControlName="enabled" |
@@ -380,7 +384,7 @@ | |||
380 | </ng-container> | 384 | </ng-container> |
381 | </my-peertube-checkbox> | 385 | </my-peertube-checkbox> |
382 | </div> | 386 | </div> |
383 | 387 | ||
384 | </ng-container> | 388 | </ng-container> |
385 | </ng-container> | 389 | </ng-container> |
386 | </ng-container> | 390 | </ng-container> |
@@ -490,10 +494,12 @@ | |||
490 | </div> | 494 | </div> |
491 | 495 | ||
492 | </ng-template> | 496 | </ng-template> |
493 | </ngb-tab> | 497 | </ng-container> |
498 | |||
499 | <ng-container ngbNavItem="services"> | ||
500 | <a ngbNavLink i18n>Services</a> | ||
494 | 501 | ||
495 | <ngb-tab id="services" i18n-title title="Services"> | 502 | <ng-template ngbNavContent> |
496 | <ng-template ngbTabContent> | ||
497 | 503 | ||
498 | <div class="form-row mt-5"> <!-- twitter grid --> | 504 | <div class="form-row mt-5"> <!-- twitter grid --> |
499 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 505 | <div class="form-group col-12 col-lg-4 col-xl-3"> |
@@ -541,12 +547,13 @@ | |||
541 | 547 | ||
542 | </div> | 548 | </div> |
543 | </div> | 549 | </div> |
550 | </ng-template> | ||
551 | </ng-container> | ||
544 | 552 | ||
545 | </ng-template> | 553 | <ng-container ngbNavItem="advanced-configuration"> |
546 | </ngb-tab> | 554 | <a ngbNavLink i18n>Advanced configuration</a> |
547 | 555 | ||
548 | <ngb-tab id="advanced-configuration" i18n-title title="Advanced configuration"> | 556 | <ng-template ngbNavContent> |
549 | <ng-template ngbTabContent> | ||
550 | 557 | ||
551 | <div class="form-row mt-5"> <!-- transcoding grid --> | 558 | <div class="form-row mt-5"> <!-- transcoding grid --> |
552 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 559 | <div class="form-group col-12 col-lg-4 col-xl-3"> |
@@ -566,7 +573,7 @@ | |||
566 | <ng-template ptTemplate="label"> | 573 | <ng-template ptTemplate="label"> |
567 | <ng-container i18n>Transcoding enabled</ng-container> | 574 | <ng-container i18n>Transcoding enabled</ng-container> |
568 | </ng-template> | 575 | </ng-template> |
569 | 576 | ||
570 | <ng-template ptTemplate="help"> | 577 | <ng-template ptTemplate="help"> |
571 | <ng-container i18n>If you disable transcoding, many videos from your users will not work!</ng-container> | 578 | <ng-container i18n>If you disable transcoding, many videos from your users will not work!</ng-container> |
572 | </ng-template> | 579 | </ng-template> |
@@ -583,7 +590,7 @@ | |||
583 | </ng-container> | 590 | </ng-container> |
584 | </my-peertube-checkbox> | 591 | </my-peertube-checkbox> |
585 | </div> | 592 | </div> |
586 | 593 | ||
587 | <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }"> | 594 | <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }"> |
588 | <my-peertube-checkbox | 595 | <my-peertube-checkbox |
589 | inputName="transcodingAllowAudioFiles" formControlName="allowAudioFiles" | 596 | inputName="transcodingAllowAudioFiles" formControlName="allowAudioFiles" |
@@ -604,7 +611,7 @@ | |||
604 | <ng-template ptTemplate="help"> | 611 | <ng-template ptTemplate="help"> |
605 | <ng-container i18n> | 612 | <ng-container i18n> |
606 | <strong>Experimental, we suggest you to not disable webtorrent support for now</strong> | 613 | <strong>Experimental, we suggest you to not disable webtorrent support for now</strong> |
607 | 614 | ||
608 | <p>If you also enabled HLS support, it will multiply videos storage by 2</p> | 615 | <p>If you also enabled HLS support, it will multiply videos storage by 2</p> |
609 | 616 | ||
610 | <br /> | 617 | <br /> |
@@ -625,14 +632,14 @@ | |||
625 | <ng-template ptTemplate="help"> | 632 | <ng-template ptTemplate="help"> |
626 | <ng-container i18n> | 633 | <ng-container i18n> |
627 | <strong>Requires ffmpeg >= 4.1</strong> | 634 | <strong>Requires ffmpeg >= 4.1</strong> |
628 | 635 | ||
629 | <p>Generate HLS playlists and fragmented MP4 files resulting in a better playback than with the current default player:</p> | 636 | <p>Generate HLS playlists and fragmented MP4 files resulting in a better playback than with the current default player:</p> |
630 | <ul> | 637 | <ul> |
631 | <li>Resolution change is smoother</li> | 638 | <li>Resolution change is smoother</li> |
632 | <li>Faster playback in particular with long videos</li> | 639 | <li>Faster playback in particular with long videos</li> |
633 | <li>More stable playback (less bugs/infinite loading)</li> | 640 | <li>More stable playback (less bugs/infinite loading)</li> |
634 | </ul> | 641 | </ul> |
635 | 642 | ||
636 | <p>If you also enabled WebTorrent support, it will multiply videos storage by 2</p> | 643 | <p>If you also enabled WebTorrent support, it will multiply videos storage by 2</p> |
637 | </ng-container> | 644 | </ng-container> |
638 | </ng-template> | 645 | </ng-template> |
@@ -785,8 +792,10 @@ | |||
785 | </div> | 792 | </div> |
786 | 793 | ||
787 | </ng-template> | 794 | </ng-template> |
788 | </ngb-tab> | 795 | </ng-container> |
789 | </ngb-tabset> | 796 | </div> |
797 | |||
798 | <div [ngbNavOutlet]="nav"></div> | ||
790 | 799 | ||
791 | <div class="form-row mt-4"> <!-- submit placement block --> | 800 | <div class="form-row mt-4"> <!-- submit placement block --> |
792 | <div class="col-md-7 col-xl-5"></div> | 801 | <div class="col-md-7 col-xl-5"></div> |
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 d81859d5c..cea314cea 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 | |||
@@ -1,4 +1,4 @@ | |||
1 | import { Component, OnInit, AfterViewChecked, ViewChild } from '@angular/core' | 1 | import { AfterViewChecked, Component, OnInit, ViewChild } from '@angular/core' |
2 | import { ConfigService } from '@app/+admin/config/shared/config.service' | 2 | import { ConfigService } from '@app/+admin/config/shared/config.service' |
3 | import { ServerService } from '@app/core/server/server.service' | 3 | import { ServerService } from '@app/core/server/server.service' |
4 | import { CustomConfigValidatorsService, FormReactive, UserValidatorsService } from '@app/shared' | 4 | import { CustomConfigValidatorsService, FormReactive, UserValidatorsService } from '@app/shared' |
@@ -10,7 +10,7 @@ import { SelectItem } from 'primeng/api' | |||
10 | import { forkJoin } from 'rxjs' | 10 | import { forkJoin } from 'rxjs' |
11 | import { ServerConfig } from '@shared/models' | 11 | import { ServerConfig } from '@shared/models' |
12 | import { ViewportScroller } from '@angular/common' | 12 | import { ViewportScroller } from '@angular/common' |
13 | import { NgbTabset } from '@ng-bootstrap/ng-bootstrap' | 13 | import { NgbNav } from '@ng-bootstrap/ng-bootstrap' |
14 | 14 | ||
15 | @Component({ | 15 | @Component({ |
16 | selector: 'my-edit-custom-config', | 16 | selector: 'my-edit-custom-config', |
@@ -18,7 +18,8 @@ import { NgbTabset } from '@ng-bootstrap/ng-bootstrap' | |||
18 | styleUrls: [ './edit-custom-config.component.scss' ] | 18 | styleUrls: [ './edit-custom-config.component.scss' ] |
19 | }) | 19 | }) |
20 | export class EditCustomConfigComponent extends FormReactive implements OnInit, AfterViewChecked { | 20 | export class EditCustomConfigComponent extends FormReactive implements OnInit, AfterViewChecked { |
21 | @ViewChild('tabs') tabs: NgbTabset | 21 | // FIXME: use built-in router |
22 | @ViewChild('nav') nav: NgbNav | ||
22 | 23 | ||
23 | initDone = false | 24 | initDone = false |
24 | customConfig: CustomConfig | 25 | customConfig: CustomConfig |
@@ -286,13 +287,13 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit, A | |||
286 | } | 287 | } |
287 | 288 | ||
288 | gotoAnchor () { | 289 | gotoAnchor () { |
289 | const hashToTab = { | 290 | const hashToNav = { |
290 | 'customizations': 'advanced-configuration' | 291 | 'customizations': 'advanced-configuration' |
291 | } | 292 | } |
292 | const hash = window.location.hash.replace('#', '') | 293 | const hash = window.location.hash.replace('#', '') |
293 | 294 | ||
294 | if (hash && Object.keys(hashToTab).includes(hash)) { | 295 | if (hash && Object.keys(hashToNav).includes(hash)) { |
295 | this.tabs.select(hashToTab[hash]) | 296 | this.nav.select(hashToNav[hash]) |
296 | setTimeout(() => this.viewportScroller.scrollToAnchor(hash), 100) | 297 | setTimeout(() => this.viewportScroller.scrollToAnchor(hash), 100) |
297 | } | 298 | } |
298 | } | 299 | } |
diff --git a/client/src/app/shared/forms/markdown-textarea.component.html b/client/src/app/shared/forms/markdown-textarea.component.html index 0925b9ad5..fb6e1343d 100644 --- a/client/src/app/shared/forms/markdown-textarea.component.html +++ b/client/src/app/shared/forms/markdown-textarea.component.html | |||
@@ -5,13 +5,23 @@ | |||
5 | [id]="name" [name]="name"> | 5 | [id]="name" [name]="name"> |
6 | </textarea> | 6 | </textarea> |
7 | 7 | ||
8 | <ngb-tabset *ngIf="arePreviewsDisplayed()" class="previews" type="pills"> | 8 | <div ngbNav #nav="ngbNav" class="nav-pills previews"> |
9 | <ngb-tab *ngIf="truncate !== undefined" i18n-title title="Truncated preview"> | 9 | <ng-container ngbNavItem *ngIf="truncate !== undefined"> |
10 | <ng-template ngbTabContent><div [innerHTML]="truncatedPreviewHTML"></div></ng-template> | 10 | <a ngbNavLink i18n>Truncated preview</a> |
11 | </ngb-tab> | ||
12 | 11 | ||
13 | <ngb-tab i18n-title title="Complete preview"> | 12 | <ng-template ngbNavContent> |
14 | <ng-template ngbTabContent><div [innerHTML]="previewHTML"></div></ng-template> | 13 | <div [innerHTML]="truncatedPreviewHTML"></div> |
15 | </ngb-tab> | 14 | </ng-template> |
16 | </ngb-tabset> | 15 | </ng-container> |
16 | |||
17 | <ng-container ngbNavItem> | ||
18 | <a ngbNavLink i18n>Complete preview</a> | ||
19 | |||
20 | <ng-template ngbNavContent> | ||
21 | <div [innerHTML]="previewHTML"></div> | ||
22 | </ng-template> | ||
23 | </ng-container> | ||
24 | </div> | ||
25 | |||
26 | <div [ngbNavOutlet]="nav"></div> | ||
17 | </div> | 27 | </div> |
diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts index b89f0a8d1..a952880a6 100644 --- a/client/src/app/shared/shared.module.ts +++ b/client/src/app/shared/shared.module.ts | |||
@@ -58,7 +58,7 @@ import { | |||
58 | NgbDropdownModule, | 58 | NgbDropdownModule, |
59 | NgbModalModule, | 59 | NgbModalModule, |
60 | NgbPopoverModule, | 60 | NgbPopoverModule, |
61 | NgbTabsetModule, | 61 | NgbNavModule, |
62 | NgbTooltipModule | 62 | NgbTooltipModule |
63 | } from '@ng-bootstrap/ng-bootstrap' | 63 | } from '@ng-bootstrap/ng-bootstrap' |
64 | import { RemoteSubscribeComponent, SubscribeButtonComponent, UserSubscriptionService } from '@app/shared/user-subscription' | 64 | import { RemoteSubscribeComponent, SubscribeButtonComponent, UserSubscriptionService } from '@app/shared/user-subscription' |
@@ -119,7 +119,7 @@ import { ActorAvatarInfoComponent } from '@app/+my-account/shared/actor-avatar-i | |||
119 | NgbDropdownModule, | 119 | NgbDropdownModule, |
120 | NgbModalModule, | 120 | NgbModalModule, |
121 | NgbPopoverModule, | 121 | NgbPopoverModule, |
122 | NgbTabsetModule, | 122 | NgbNavModule, |
123 | NgbTooltipModule, | 123 | NgbTooltipModule, |
124 | NgbCollapseModule, | 124 | NgbCollapseModule, |
125 | 125 | ||
@@ -204,7 +204,7 @@ import { ActorAvatarInfoComponent } from '@app/+my-account/shared/actor-avatar-i | |||
204 | NgbDropdownModule, | 204 | NgbDropdownModule, |
205 | NgbModalModule, | 205 | NgbModalModule, |
206 | NgbPopoverModule, | 206 | NgbPopoverModule, |
207 | NgbTabsetModule, | 207 | NgbNavModule, |
208 | NgbTooltipModule, | 208 | NgbTooltipModule, |
209 | NgbCollapseModule, | 209 | NgbCollapseModule, |
210 | 210 | ||
diff --git a/client/src/app/shared/video/modals/video-download.component.html b/client/src/app/shared/video/modals/video-download.component.html index 391fe245e..ab6f4449d 100644 --- a/client/src/app/shared/video/modals/video-download.component.html +++ b/client/src/app/shared/video/modals/video-download.component.html | |||
@@ -1,7 +1,7 @@ | |||
1 | <ng-template #modal let-hide="close"> | 1 | <ng-template #modal let-hide="close"> |
2 | <div class="modal-header"> | 2 | <div class="modal-header"> |
3 | <h4 class="modal-title">Download | 3 | <h4 class="modal-title"> |
4 | <span *ngIf="!videoCaptions" i18n>video</span> | 4 | <ng-container i18n>Download</ng-container> |
5 | 5 | ||
6 | <div *ngIf="videoCaptions" ngbDropdown class="d-inline-block"> | 6 | <div *ngIf="videoCaptions" ngbDropdown class="d-inline-block"> |
7 | <span id="dropdownDownloadType" ngbDropdownToggle> | 7 | <span id="dropdownDownloadType" ngbDropdownToggle> |
@@ -38,41 +38,48 @@ | |||
38 | </div> | 38 | </div> |
39 | </div> | 39 | </div> |
40 | 40 | ||
41 | <ngb-tabset *ngIf="type === 'video' && videoFile?.metadata"> | 41 | <ng-container *ngIf="type === 'video' && videoFile?.metadata"> |
42 | <ngb-tab> | 42 | <div ngbNav #nav="ngbNav" class="nav-tabs"> |
43 | <ng-template ngbTabTitle i18n>Format</ng-template> | 43 | |
44 | <ng-template ngbTabContent> | 44 | <ng-container ngbNavItem> |
45 | <div class="file-metadata"> | 45 | <a ngbNavLink i18n>Format</a> |
46 | <div class="metadata-attribute metadata-attribute-tags" *ngFor="let item of videoFileMetadataFormat | keyvalue"> | 46 | <ng-template ngbNavContent> |
47 | <span i18n class="metadata-attribute-label">{{ item.value.label }}</span> | 47 | <div class="file-metadata"> |
48 | <span class="metadata-attribute-value">{{ item.value.value }}</span> | 48 | <div class="metadata-attribute metadata-attribute-tags" *ngFor="let item of videoFileMetadataFormat | keyvalue"> |
49 | <span i18n class="metadata-attribute-label">{{ item.value.label }}</span> | ||
50 | <span class="metadata-attribute-value">{{ item.value.value }}</span> | ||
51 | </div> | ||
49 | </div> | 52 | </div> |
50 | </div> | 53 | </ng-template> |
51 | </ng-template> | 54 | </ng-container> |
52 | </ngb-tab> | 55 | |
53 | <ngb-tab [disabled]="videoFileMetadataVideoStream === undefined"> | 56 | <ng-container ngbNavItem [disabled]="videoFileMetadataVideoStream === undefined"> |
54 | <ng-template ngbTabTitle i18n>Video stream</ng-template> | 57 | <a ngbNavLink i18n>Video stream</a> |
55 | <ng-template ngbTabContent> | 58 | <ng-template ngbNavContent> |
56 | <div class="file-metadata"> | 59 | <div class="file-metadata"> |
57 | <div class="metadata-attribute metadata-attribute-tags" *ngFor="let item of videoFileMetadataVideoStream | keyvalue"> | 60 | <div class="metadata-attribute metadata-attribute-tags" *ngFor="let item of videoFileMetadataVideoStream | keyvalue"> |
58 | <span i18n class="metadata-attribute-label">{{ item.value.label }}</span> | 61 | <span i18n class="metadata-attribute-label">{{ item.value.label }}</span> |
59 | <span class="metadata-attribute-value">{{ item.value.value }}</span> | 62 | <span class="metadata-attribute-value">{{ item.value.value }}</span> |
63 | </div> | ||
60 | </div> | 64 | </div> |
61 | </div> | 65 | </ng-template> |
62 | </ng-template> | 66 | </ng-container> |
63 | </ngb-tab> | 67 | |
64 | <ngb-tab [disabled]="videoFileMetadataAudioStream === undefined"> | 68 | <ng-container ngbNavItem [disabled]="videoFileMetadataAudioStream === undefined"> |
65 | <ng-template ngbTabTitle i18n>Audio stream</ng-template> | 69 | <a ngbNavLink i18n>Audio stream</a> |
66 | <ng-template ngbTabContent> | 70 | <ng-template ngbNavContent> |
67 | <div class="file-metadata"> | 71 | <div class="file-metadata"> |
68 | <div class="metadata-attribute metadata-attribute-tags" *ngFor="let item of videoFileMetadataAudioStream | keyvalue"> | 72 | <div class="metadata-attribute metadata-attribute-tags" *ngFor="let item of videoFileMetadataAudioStream | keyvalue"> |
69 | <span i18n class="metadata-attribute-label">{{ item.value.label }}</span> | 73 | <span i18n class="metadata-attribute-label">{{ item.value.label }}</span> |
70 | <span class="metadata-attribute-value">{{ item.value.value }}</span> | 74 | <span class="metadata-attribute-value">{{ item.value.value }}</span> |
75 | </div> | ||
71 | </div> | 76 | </div> |
72 | </div> | 77 | </ng-template> |
73 | </ng-template> | 78 | </ng-container> |
74 | </ngb-tab> | 79 | </div> |
75 | </ngb-tabset> | 80 | |
81 | <div [ngbNavOutlet]="nav"></div> | ||
82 | </ng-container> | ||
76 | 83 | ||
77 | <div class="download-type" *ngIf="type === 'video'"> | 84 | <div class="download-type" *ngIf="type === 'video'"> |
78 | <div class="peertube-radio-container"> | 85 | <div class="peertube-radio-container"> |
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 6d72e5765..967f3b188 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 | |||
@@ -1,8 +1,10 @@ | |||
1 | <div class="video-edit" [formGroup]="form"> | 1 | <div class="video-edit" [formGroup]="form"> |
2 | <ngb-tabset class="root-tabset bootstrap"> | 2 | <div ngbNav #nav="ngbNav" class="nav-tabs"> |
3 | 3 | ||
4 | <ngb-tab i18n-title title="Basic info"> | 4 | <ng-container ngbNavItem> |
5 | <ng-template ngbTabContent> | 5 | <a ngbNavLink i18n>Basic info</a> |
6 | |||
7 | <ng-template ngbNavContent> | ||
6 | <div class="row"> | 8 | <div class="row"> |
7 | <div class="col-md-8"> | 9 | <div class="col-md-8"> |
8 | <div class="form-group"> | 10 | <div class="form-group"> |
@@ -155,10 +157,12 @@ | |||
155 | </div> | 157 | </div> |
156 | </div> | 158 | </div> |
157 | </ng-template> | 159 | </ng-template> |
158 | </ngb-tab> | 160 | </ng-container> |
161 | |||
162 | <ng-container ngbNavItem> | ||
163 | <a ngbNavLink i18n>Captions</a> | ||
159 | 164 | ||
160 | <ngb-tab i18n-title title="Captions"> | 165 | <ng-template ngbNavContent> |
161 | <ng-template ngbTabContent> | ||
162 | <div class="captions"> | 166 | <div class="captions"> |
163 | 167 | ||
164 | <div class="captions-header"> | 168 | <div class="captions-header"> |
@@ -206,10 +210,12 @@ | |||
206 | 210 | ||
207 | </div> | 211 | </div> |
208 | </ng-template> | 212 | </ng-template> |
209 | </ngb-tab> | 213 | </ng-container> |
214 | |||
215 | <ng-container ngbNavItem> | ||
216 | <a ngbNavLink i18n>Advanced settings</a> | ||
210 | 217 | ||
211 | <ngb-tab i18n-title title="Advanced settings"> | 218 | <ng-template ngbNavContent> |
212 | <ng-template ngbTabContent> | ||
213 | <div class="row advanced-settings"> | 219 | <div class="row advanced-settings"> |
214 | <div class="col-md-12 col-xl-8"> | 220 | <div class="col-md-12 col-xl-8"> |
215 | 221 | ||
@@ -262,10 +268,11 @@ | |||
262 | </div> | 268 | </div> |
263 | </div> | 269 | </div> |
264 | </ng-template> | 270 | </ng-template> |
265 | </ngb-tab> | 271 | </ng-container> |
266 | 272 | ||
267 | </ngb-tabset> | 273 | </div> |
268 | 274 | ||
275 | <div [ngbNavOutlet]="nav"></div> | ||
269 | </div> | 276 | </div> |
270 | 277 | ||
271 | <my-video-caption-add-modal | 278 | <my-video-caption-add-modal |
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 144914731..90d26e13d 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 | |||
@@ -19,6 +19,10 @@ my-peertube-checkbox { | |||
19 | margin-bottom: 1rem; | 19 | margin-bottom: 1rem; |
20 | } | 20 | } |
21 | 21 | ||
22 | .nav-tabs { | ||
23 | margin-bottom: 15px; | ||
24 | } | ||
25 | |||
22 | .video-edit { | 26 | .video-edit { |
23 | height: 100%; | 27 | height: 100%; |
24 | min-height: 300px; | 28 | min-height: 300px; |
@@ -145,10 +149,6 @@ p-calendar { | |||
145 | } | 149 | } |
146 | 150 | ||
147 | ::ng-deep { | 151 | ::ng-deep { |
148 | .root-tabset > .nav { | ||
149 | margin-bottom: 15px; | ||
150 | } | ||
151 | |||
152 | .ng2-tag-input { | 152 | .ng2-tag-input { |
153 | border: none !important; | 153 | border: none !important; |
154 | } | 154 | } |
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 a99988600..79bfc6e5c 100644 --- a/client/src/app/videos/+video-edit/video-add.component.html +++ b/client/src/app/videos/+video-edit/video-add.component.html | |||
@@ -10,27 +10,37 @@ | |||
10 | <ng-container *ngIf="secondStepType === 'upload'" i18n>Upload {{ videoName }}</ng-container> | 10 | <ng-container *ngIf="secondStepType === 'upload'" i18n>Upload {{ videoName }}</ng-container> |
11 | </div> | 11 | </div> |
12 | 12 | ||
13 | <ngb-tabset class="video-add-tabset root-tabset bootstrap" [ngClass]="{ 'hide-nav': secondStepType !== undefined }"> | 13 | <div ngbNav #nav="ngbNav" class="nav-tabs video-add-nav" [ngClass]="{ 'hide-nav': secondStepType !== undefined }"> |
14 | <ng-container ngbNavItem> | ||
15 | <a ngbNavLink> | ||
16 | <span i18n>Upload a file</span> | ||
17 | </a> | ||
14 | 18 | ||
15 | <ngb-tab> | 19 | <ng-template ngbNavContent> |
16 | <ng-template ngbTabTitle><span i18n>Upload a file</span></ng-template> | ||
17 | <ng-template ngbTabContent> | ||
18 | <my-video-upload #videoUpload (firstStepDone)="onFirstStepDone('upload', $event)" (firstStepError)="onError()"></my-video-upload> | 20 | <my-video-upload #videoUpload (firstStepDone)="onFirstStepDone('upload', $event)" (firstStepError)="onError()"></my-video-upload> |
19 | </ng-template> | 21 | </ng-template> |
20 | </ngb-tab> | 22 | </ng-container> |
21 | 23 | ||
22 | <ngb-tab *ngIf="isVideoImportHttpEnabled()"> | 24 | <ng-container ngbNavItem *ngIf="isVideoImportHttpEnabled()"> |
23 | <ng-template ngbTabTitle><span i18n>Import with URL</span></ng-template> | 25 | <a ngbNavLink> |
24 | <ng-template ngbTabContent> | 26 | <span i18n>Import with URL</span> |
27 | </a> | ||
28 | |||
29 | <ng-template ngbNavContent> | ||
25 | <my-video-import-url #videoImportUrl (firstStepDone)="onFirstStepDone('import-url', $event)" (firstStepError)="onError()"></my-video-import-url> | 30 | <my-video-import-url #videoImportUrl (firstStepDone)="onFirstStepDone('import-url', $event)" (firstStepError)="onError()"></my-video-import-url> |
26 | </ng-template> | 31 | </ng-template> |
27 | </ngb-tab> | 32 | </ng-container> |
33 | |||
34 | <ng-container ngbNavItem *ngIf="isVideoImportTorrentEnabled()"> | ||
35 | <a ngbNavLink> | ||
36 | <span i18n>Import with torrent</span> | ||
37 | </a> | ||
28 | 38 | ||
29 | <ngb-tab *ngIf="isVideoImportTorrentEnabled()"> | 39 | <ng-template ngbNavContent> |
30 | <ng-template ngbTabTitle><span i18n>Import with torrent</span></ng-template> | ||
31 | <ng-template ngbTabContent> | ||
32 | <my-video-import-torrent #videoImportTorrent (firstStepDone)="onFirstStepDone('import-torrent', $event)" (firstStepError)="onError()"></my-video-import-torrent> | 40 | <my-video-import-torrent #videoImportTorrent (firstStepDone)="onFirstStepDone('import-torrent', $event)" (firstStepError)="onError()"></my-video-import-torrent> |
33 | </ng-template> | 41 | </ng-template> |
34 | </ngb-tab> | 42 | </ng-container> |
35 | </ngb-tabset> | 43 | </div> |
44 | |||
45 | <div [ngbNavOutlet]="nav"></div> | ||
36 | </div> | 46 | </div> |
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 7acab3744..9d068afde 100644 --- a/client/src/app/videos/+video-edit/video-add.component.scss +++ b/client/src/app/videos/+video-edit/video-add.component.scss | |||
@@ -13,52 +13,41 @@ $border-color: #EAEAEA; | |||
13 | font-size: 15px; | 13 | font-size: 15px; |
14 | } | 14 | } |
15 | 15 | ||
16 | ::ng-deep .root-tabset.video-add-tabset { | 16 | ::ng-deep .video-add-nav { |
17 | margin-top: 50px; | 17 | border-bottom: $border-width $border-type $border-color; |
18 | 18 | margin: 50px 0 0 0 !important; | |
19 | &.hide-nav > .nav { | 19 | |
20 | display: none !important; | 20 | a.nav-link { |
21 | } | 21 | @include disable-default-a-behaviour; |
22 | 22 | ||
23 | & > .nav { | 23 | margin-bottom: -$border-width; |
24 | border-bottom: $border-width $border-type $border-color; | 24 | height: 40px !important; |
25 | margin: 0 !important; | 25 | padding: 0 30px !important; |
26 | 26 | font-size: 15px; | |
27 | & > li { | 27 | |
28 | margin-bottom: -$border-width; | 28 | &.active { |
29 | } | 29 | border: $border-width $border-type $border-color; |
30 | 30 | border-bottom: none; | |
31 | a.nav-link { | 31 | background-color: var(--submenuColor) !important; |
32 | @include disable-default-a-behaviour; | 32 | |
33 | 33 | span { | |
34 | height: 40px !important; | 34 | border-bottom: 2px solid var(--mainColor); |
35 | padding: 0 30px !important; | 35 | font-weight: $font-bold; |
36 | font-size: 15px; | ||
37 | |||
38 | &.active { | ||
39 | border: $border-width $border-type $border-color; | ||
40 | border-bottom: none; | ||
41 | background-color: var(--submenuColor) !important; | ||
42 | |||
43 | span { | ||
44 | border-bottom: 2px solid var(--mainColor); | ||
45 | font-weight: $font-bold; | ||
46 | } | ||
47 | } | 36 | } |
48 | } | 37 | } |
49 | } | 38 | } |
39 | } | ||
50 | 40 | ||
51 | .upload-video-container { | 41 | ::ng-deep .upload-video-container { |
52 | border: $border-width $border-type $border-color; | 42 | border: $border-width $border-type $border-color; |
53 | border-top: none; | 43 | border-top: none; |
54 | 44 | ||
55 | background-color: var(--submenuColor); | 45 | background-color: var(--submenuColor); |
56 | border-radius: 3px; | 46 | border-radius: 3px; |
57 | width: 100%; | 47 | width: 100%; |
58 | min-height: 440px; | 48 | min-height: 440px; |
59 | padding-bottom: 20px; | 49 | padding-bottom: 20px; |
60 | display: flex; | 50 | display: flex; |
61 | justify-content: center; | 51 | justify-content: center; |
62 | align-items: center; | 52 | align-items: center; |
63 | } | ||
64 | } | 53 | } |
diff --git a/client/src/app/videos/+video-watch/modal/video-share.component.html b/client/src/app/videos/+video-watch/modal/video-share.component.html index dd2dd34ab..5e6a2d518 100644 --- a/client/src/app/videos/+video-watch/modal/video-share.component.html +++ b/client/src/app/videos/+video-watch/modal/video-share.component.html | |||
@@ -27,29 +27,33 @@ | |||
27 | <div class="video"> | 27 | <div class="video"> |
28 | <div class="title-page title-page-single" *ngIf="hasPlaylist()" i18n>Share the video</div> | 28 | <div class="title-page title-page-single" *ngIf="hasPlaylist()" i18n>Share the video</div> |
29 | 29 | ||
30 | <ngb-tabset class="root-tabset bootstrap" (tabChange)="onTabChange($event)"> | 30 | <div ngbNav #nav="ngbNav" class="nav-tabs" [(activeId)]="activeId"> |
31 | 31 | ||
32 | <ngb-tab i18n-title title="URL" id="url"> | 32 | <ng-container ngbNavItem="url"> |
33 | <ng-template ngbTabContent> | 33 | <a ngbNavLink i18n>URL</a> |
34 | 34 | ||
35 | <div class="tab-content"> | 35 | <ng-template ngbNavContent> |
36 | <div class="nav-content"> | ||
36 | <my-input-readonly-copy [value]="getVideoUrl()"></my-input-readonly-copy> | 37 | <my-input-readonly-copy [value]="getVideoUrl()"></my-input-readonly-copy> |
37 | </div> | 38 | </div> |
38 | |||
39 | </ng-template> | 39 | </ng-template> |
40 | </ngb-tab> | 40 | </ng-container> |
41 | |||
42 | <ng-container ngbNavItem="qrcode"> | ||
43 | <a ngbNavLink i18n>QR-Code</a> | ||
41 | 44 | ||
42 | <ngb-tab i18n-title title="QR-Code" id="qrcode"> | 45 | <ng-template ngbNavContent> |
43 | <ng-template ngbTabContent> | 46 | <div class="nav-content"> |
44 | <div class="tab-content"> | ||
45 | <qrcode [qrdata]="getVideoUrl()" [size]="256" level="Q"></qrcode> | 47 | <qrcode [qrdata]="getVideoUrl()" [size]="256" level="Q"></qrcode> |
46 | </div> | 48 | </div> |
47 | </ng-template> | 49 | </ng-template> |
48 | </ngb-tab> | 50 | </ng-container> |
51 | |||
52 | <ng-container ngbNavItem="embed"> | ||
53 | <a ngbNavLink i18n>Embed</a> | ||
49 | 54 | ||
50 | <ngb-tab i18n-title title="Embed" id="embed"> | 55 | <ng-template ngbNavContent> |
51 | <ng-template ngbTabContent> | 56 | <div class="nav-content"> |
52 | <div class="tab-content"> | ||
53 | <my-input-readonly-copy [value]="getVideoIframeCode()"></my-input-readonly-copy> | 57 | <my-input-readonly-copy [value]="getVideoIframeCode()"></my-input-readonly-copy> |
54 | 58 | ||
55 | <div i18n *ngIf="notSecure()" class="alert alert-warning"> | 59 | <div i18n *ngIf="notSecure()" class="alert alert-warning"> |
@@ -57,9 +61,11 @@ | |||
57 | </div> | 61 | </div> |
58 | </div> | 62 | </div> |
59 | </ng-template> | 63 | </ng-template> |
60 | </ngb-tab> | 64 | </ng-container> |
65 | |||
66 | </div> | ||
61 | 67 | ||
62 | </ngb-tabset> | 68 | <div [ngbNavOutlet]="nav"></div> |
63 | 69 | ||
64 | <div class="filters"> | 70 | <div class="filters"> |
65 | <div> | 71 | <div> |
diff --git a/client/src/app/videos/+video-watch/modal/video-share.component.scss b/client/src/app/videos/+video-watch/modal/video-share.component.scss index 11cbb8c0b..091d4dc3b 100644 --- a/client/src/app/videos/+video-watch/modal/video-share.component.scss +++ b/client/src/app/videos/+video-watch/modal/video-share.component.scss | |||
@@ -21,7 +21,7 @@ my-input-readonly-copy { | |||
21 | text-align: center; | 21 | text-align: center; |
22 | } | 22 | } |
23 | 23 | ||
24 | .tab-content { | 24 | .nav-content { |
25 | margin-top: 30px; | 25 | margin-top: 30px; |
26 | display: flex; | 26 | display: flex; |
27 | justify-content: center; | 27 | justify-content: center; |
diff --git a/client/src/app/videos/+video-watch/modal/video-share.component.ts b/client/src/app/videos/+video-watch/modal/video-share.component.ts index 5109bcd11..56e7d70dd 100644 --- a/client/src/app/videos/+video-watch/modal/video-share.component.ts +++ b/client/src/app/videos/+video-watch/modal/video-share.component.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { Component, ElementRef, Input, ViewChild } from '@angular/core' | 1 | import { Component, ElementRef, Input, ViewChild } from '@angular/core' |
2 | import { VideoDetails } from '../../../shared/video/video-details.model' | 2 | import { VideoDetails } from '../../../shared/video/video-details.model' |
3 | import { buildVideoEmbed, buildVideoLink } from '../../../../assets/player/utils' | 3 | import { buildVideoEmbed, buildVideoLink } from '../../../../assets/player/utils' |
4 | import { NgbModal, NgbTabChangeEvent } from '@ng-bootstrap/ng-bootstrap' | 4 | import { NgbModal, NgbNavChangeEvent, NgbTabChangeEvent } from '@ng-bootstrap/ng-bootstrap' |
5 | import { VideoCaption } from '@shared/models' | 5 | import { VideoCaption } from '@shared/models' |
6 | import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model' | 6 | import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model' |
7 | 7 | ||
@@ -35,7 +35,7 @@ export class VideoShareComponent { | |||
35 | @Input() videoCaptions: VideoCaption[] = [] | 35 | @Input() videoCaptions: VideoCaption[] = [] |
36 | @Input() playlist: VideoPlaylist = null | 36 | @Input() playlist: VideoPlaylist = null |
37 | 37 | ||
38 | activeId: 'url' | 'qrcode' | 'embed' | 38 | activeId: 'url' | 'qrcode' | 'embed' = 'url' |
39 | customizations: Customizations | 39 | customizations: Customizations |
40 | isAdvancedCustomizationCollapsed = true | 40 | isAdvancedCustomizationCollapsed = true |
41 | includeVideoInPlaylist = false | 41 | includeVideoInPlaylist = false |
@@ -101,10 +101,6 @@ export class VideoShareComponent { | |||
101 | return window.location.protocol === 'http:' | 101 | return window.location.protocol === 'http:' |
102 | } | 102 | } |
103 | 103 | ||
104 | onTabChange (event: NgbTabChangeEvent) { | ||
105 | this.activeId = event.nextId as any | ||
106 | } | ||
107 | |||
108 | isInEmbedTab () { | 104 | isInEmbedTab () { |
109 | return this.activeId === 'embed' | 105 | return this.activeId === 'embed' |
110 | } | 106 | } |
diff --git a/client/src/sass/bootstrap.scss b/client/src/sass/bootstrap.scss index 5c1ce1028..297f1f18a 100644 --- a/client/src/sass/bootstrap.scss +++ b/client/src/sass/bootstrap.scss | |||
@@ -50,7 +50,7 @@ $icon-font-path: '~@neos21/bootstrap3-glyphicons/assets/fonts/'; | |||
50 | background-color: var(--mainHoverColor); | 50 | background-color: var(--mainHoverColor); |
51 | opacity: .9; | 51 | opacity: .9; |
52 | } | 52 | } |
53 | 53 | ||
54 | &::after { | 54 | &::after { |
55 | display: none; | 55 | display: none; |
56 | } | 56 | } |
@@ -158,18 +158,12 @@ $icon-font-path: '~@neos21/bootstrap3-glyphicons/assets/fonts/'; | |||
158 | } | 158 | } |
159 | } | 159 | } |
160 | 160 | ||
161 | ngb-tabset { | 161 | .nav-tabs { |
162 | 162 | ||
163 | .nav-link { | 163 | .nav-link { |
164 | &, & a { | 164 | @include disable-default-a-behaviour; |
165 | @include disable-default-a-behaviour; | ||
166 | |||
167 | color: var(--mainForegroundColor) !important; | ||
168 | } | ||
169 | } | ||
170 | 165 | ||
171 | .nav-pills .nav-link.active { | 166 | color: var(--mainForegroundColor) !important; |
172 | color: #000 !important; | ||
173 | } | 167 | } |
174 | } | 168 | } |
175 | 169 | ||