aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRigel Kent <sendmemail@rigelk.eu>2020-03-11 19:38:17 +0100
committerRigel Kent <sendmemail@rigelk.eu>2020-03-11 19:38:17 +0100
commit45e0d6697c107d77dce73d8e354867dc1959741d (patch)
tree6acff1e8fdc59ed396a3da4439461d4a475ee8b5
parent111fdc267b36201cf1be1fdf91017005102b4a5e (diff)
downloadPeerTube-45e0d6697c107d77dce73d8e354867dc1959741d.tar.gz
PeerTube-45e0d6697c107d77dce73d8e354867dc1959741d.tar.zst
PeerTube-45e0d6697c107d77dce73d8e354867dc1959741d.zip
Properly scroll to anchors in links, especially in admin config
-rw-r--r--client/src/app/+about/about-instance/about-instance.component.html5
-rw-r--r--client/src/app/+about/about-instance/about-instance.component.ts11
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html18
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts29
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-settings.component.html1
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-settings.component.ts10
-rw-r--r--client/src/sass/application.scss5
7 files changed, 62 insertions, 17 deletions
diff --git a/client/src/app/+about/about-instance/about-instance.component.html b/client/src/app/+about/about-instance/about-instance.component.html
index 043f63354..1df1ef2ad 100644
--- a/client/src/app/+about/about-instance/about-instance.component.html
+++ b/client/src/app/+about/about-instance/about-instance.component.html
@@ -96,9 +96,8 @@
96 </div> 96 </div>
97 97
98 <div class="col"> 98 <div class="col">
99 <div id="statistics" i18n class="middle-title"> 99 <div class="anchor" id="statistics"></div>
100 STATISTICS 100 <div i18n class="middle-title">STATISTICS</div>
101 </div>
102 <my-instance-statistics></my-instance-statistics> 101 <my-instance-statistics></my-instance-statistics>
103 </div> 102 </div>
104</div> 103</div>
diff --git a/client/src/app/+about/about-instance/about-instance.component.ts b/client/src/app/+about/about-instance/about-instance.component.ts
index c8c156105..e1809d7b7 100644
--- a/client/src/app/+about/about-instance/about-instance.component.ts
+++ b/client/src/app/+about/about-instance/about-instance.component.ts
@@ -1,17 +1,18 @@
1import { Component, OnInit, ViewChild } from '@angular/core' 1import { Component, OnInit, ViewChild, AfterViewChecked } from '@angular/core'
2import { Notifier, ServerService } from '@app/core' 2import { Notifier, ServerService } from '@app/core'
3import { ContactAdminModalComponent } from '@app/+about/about-instance/contact-admin-modal.component' 3import { ContactAdminModalComponent } from '@app/+about/about-instance/contact-admin-modal.component'
4import { InstanceService } from '@app/shared/instance/instance.service' 4import { InstanceService } from '@app/shared/instance/instance.service'
5import { ServerConfig } from '@shared/models' 5import { ServerConfig } from '@shared/models'
6import { ActivatedRoute } from '@angular/router' 6import { ActivatedRoute } from '@angular/router'
7import { ResolverData } from './about-instance.resolver' 7import { ResolverData } from './about-instance.resolver'
8import { ViewportScroller } from '@angular/common'
8 9
9@Component({ 10@Component({
10 selector: 'my-about-instance', 11 selector: 'my-about-instance',
11 templateUrl: './about-instance.component.html', 12 templateUrl: './about-instance.component.html',
12 styleUrls: [ './about-instance.component.scss' ] 13 styleUrls: [ './about-instance.component.scss' ]
13}) 14})
14export class AboutInstanceComponent implements OnInit { 15export class AboutInstanceComponent implements OnInit, AfterViewChecked {
15 @ViewChild('contactAdminModal', { static: true }) contactAdminModal: ContactAdminModalComponent 16 @ViewChild('contactAdminModal', { static: true }) contactAdminModal: ContactAdminModalComponent
16 17
17 shortDescription = '' 18 shortDescription = ''
@@ -35,8 +36,8 @@ export class AboutInstanceComponent implements OnInit {
35 serverConfig: ServerConfig 36 serverConfig: ServerConfig
36 37
37 constructor ( 38 constructor (
39 private viewportScroller: ViewportScroller,
38 private route: ActivatedRoute, 40 private route: ActivatedRoute,
39 private notifier: Notifier,
40 private serverService: ServerService, 41 private serverService: ServerService,
41 private instanceService: InstanceService 42 private instanceService: InstanceService
42 ) {} 43 ) {}
@@ -72,6 +73,10 @@ export class AboutInstanceComponent implements OnInit {
72 this.html = await this.instanceService.buildHtml(about) 73 this.html = await this.instanceService.buildHtml(about)
73 } 74 }
74 75
76 ngAfterViewChecked () {
77 if (window.location.hash) this.viewportScroller.scrollToAnchor(window.location.hash.replace('#', ''))
78 }
79
75 openContactModal () { 80 openContactModal () {
76 return this.contactAdminModal.show() 81 return this.contactAdminModal.show()
77 } 82 }
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 be89d8294..b3b4f7728 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,8 +1,8 @@
1<form role="form" [formGroup]="form"> 1<form role="form" [formGroup]="form">
2 2
3 <ngb-tabset class="root-tabset bootstrap"> 3 <ngb-tabset #tabs class="root-tabset bootstrap">
4 4
5 <ngb-tab i18n-title title="Instance information"> 5 <ngb-tab id="instance-information" i18n-title title="Instance information">
6 <ng-template ngbTabContent> 6 <ng-template ngbTabContent>
7 7
8 <ng-container formGroupName="instance"> 8 <ng-container formGroupName="instance">
@@ -210,7 +210,7 @@
210 210
211 <div class="form-group"> 211 <div class="form-group">
212 <label i18n for="instanceHardwareInformation">What server/hardware does the instance run on?</label> 212 <label i18n for="instanceHardwareInformation">What server/hardware does the instance run on?</label>
213 <div i18n class="label-small-info">2vCore 2GB RAM/or directly the link to the server you rent etc</div> 213 <div i18n class="label-small-info">i.e. 2vCore 2GB RAM, a direct the link to the server you rent, etc.</div>
214 214
215 <my-markdown-textarea 215 <my-markdown-textarea
216 name="instanceHardwareInformation" formControlName="hardwareInformation" textareaWidth="500px" textareaHeight="75px" [previewColumn]="true" 216 name="instanceHardwareInformation" formControlName="hardwareInformation" textareaWidth="500px" textareaHeight="75px" [previewColumn]="true"
@@ -227,14 +227,14 @@
227 </ng-template> 227 </ng-template>
228 </ngb-tab> 228 </ngb-tab>
229 229
230 <ngb-tab i18n-title title="Basic configuration"> 230 <ngb-tab id="basic-configuration" i18n-title title="Basic configuration">
231 <ng-template ngbTabContent> 231 <ng-template ngbTabContent>
232 232
233 <div class="form-row mt-5"> <!-- appearance grid --> 233 <div class="form-row mt-5"> <!-- appearance grid -->
234 <div class="form-group col-12 col-lg-4 col-xl-3"> 234 <div class="form-group col-12 col-lg-4 col-xl-3">
235 <div i18n class="inner-form-title">APPEARANCE</div> 235 <div i18n class="inner-form-title">APPEARANCE</div>
236 <div i18n class="inner-for-description"> 236 <div i18n class="inner-for-description">
237 Use <a routerLink="/admin/plugins">plugins & themes</a> for more involved changes. 237 Use <a routerLink="/admin/plugins">plugins & themes</a> for more involved changes, or <a routerLink="/admin/config/edit-custom" fragment="customizations" (click)="gotoAnchor()">add slight customizations</a>.
238 </div> 238 </div>
239 </div> 239 </div>
240 240
@@ -391,6 +391,9 @@
391 <div class="form-row mt-4"> <!-- federation grid --> 391 <div class="form-row mt-4"> <!-- federation grid -->
392 <div class="form-group col-12 col-lg-4 col-xl-3"> 392 <div class="form-group col-12 col-lg-4 col-xl-3">
393 <div i18n class="inner-form-title">FEDERATION</div> 393 <div i18n class="inner-form-title">FEDERATION</div>
394 <div i18n class="inner-form-description">
395 Manage <a routerLink="/admin/follows">relations</a> with other instances.
396 </div>
394 </div> 397 </div>
395 398
396 <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> 399 <div class="form-group form-group-right col-12 col-lg-8 col-xl-9">
@@ -489,7 +492,7 @@
489 </ng-template> 492 </ng-template>
490 </ngb-tab> 493 </ngb-tab>
491 494
492 <ngb-tab i18n-title title="Services"> 495 <ngb-tab id="services" i18n-title title="Services">
493 <ng-template ngbTabContent> 496 <ng-template ngbTabContent>
494 497
495 <div class="form-row mt-5"> <!-- twitter grid --> 498 <div class="form-row mt-5"> <!-- twitter grid -->
@@ -542,7 +545,7 @@
542 </ng-template> 545 </ng-template>
543 </ngb-tab> 546 </ngb-tab>
544 547
545 <ngb-tab i18n-title title="Advanced configuration"> 548 <ngb-tab id="advanced-configuration" i18n-title title="Advanced configuration">
546 <ng-template ngbTabContent> 549 <ng-template ngbTabContent>
547 550
548 <div class="form-row mt-5"> <!-- transcoding grid --> 551 <div class="form-row mt-5"> <!-- transcoding grid -->
@@ -718,6 +721,7 @@
718 721
719 <div class="form-row mt-4"> <!-- cache grid --> 722 <div class="form-row mt-4"> <!-- cache grid -->
720 <div class="form-group col-12 col-lg-4 col-xl-3"> 723 <div class="form-group col-12 col-lg-4 col-xl-3">
724 <div class="anchor" id="customizations"></div> <!-- customizations anchor -->
721 <div i18n class="inner-form-title">CUSTOMIZATIONS</div> 725 <div i18n class="inner-form-title">CUSTOMIZATIONS</div>
722 <div i18n class="inner-form-description"> 726 <div i18n class="inner-form-description">
723 Slight modifications to your PeerTube instance for when creating a plugin or theme is overkill. 727 Slight modifications to your PeerTube instance for when creating a plugin or theme is overkill.
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 c88e81c01..c3eac68bb 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 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit, AfterViewChecked, ViewChild } from '@angular/core'
2import { ConfigService } from '@app/+admin/config/shared/config.service' 2import { ConfigService } from '@app/+admin/config/shared/config.service'
3import { ServerService } from '@app/core/server/server.service' 3import { ServerService } from '@app/core/server/server.service'
4import { CustomConfigValidatorsService, FormReactive, UserValidatorsService } from '@app/shared' 4import { CustomConfigValidatorsService, FormReactive, UserValidatorsService } from '@app/shared'
@@ -9,13 +9,18 @@ import { FormValidatorService } from '@app/shared/forms/form-validators/form-val
9import { SelectItem } from 'primeng/api' 9import { SelectItem } from 'primeng/api'
10import { forkJoin } from 'rxjs' 10import { forkJoin } from 'rxjs'
11import { ServerConfig } from '@shared/models' 11import { ServerConfig } from '@shared/models'
12import { ViewportScroller } from '@angular/common'
13import { NgbTabset } from '@ng-bootstrap/ng-bootstrap'
12 14
13@Component({ 15@Component({
14 selector: 'my-edit-custom-config', 16 selector: 'my-edit-custom-config',
15 templateUrl: './edit-custom-config.component.html', 17 templateUrl: './edit-custom-config.component.html',
16 styleUrls: [ './edit-custom-config.component.scss' ] 18 styleUrls: [ './edit-custom-config.component.scss' ]
17}) 19})
18export class EditCustomConfigComponent extends FormReactive implements OnInit { 20export class EditCustomConfigComponent extends FormReactive implements OnInit, AfterViewChecked {
21 @ViewChild('tabs') private tabs: NgbTabset
22
23 initDone = false
19 customConfig: CustomConfig 24 customConfig: CustomConfig
20 25
21 resolutions: { id: string, label: string, description?: string }[] = [] 26 resolutions: { id: string, label: string, description?: string }[] = []
@@ -27,6 +32,7 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
27 private serverConfig: ServerConfig 32 private serverConfig: ServerConfig
28 33
29 constructor ( 34 constructor (
35 private viewportScroller: ViewportScroller,
30 protected formValidatorService: FormValidatorService, 36 protected formValidatorService: FormValidatorService,
31 private customConfigValidatorsService: CustomConfigValidatorsService, 37 private customConfigValidatorsService: CustomConfigValidatorsService,
32 private userValidatorsService: UserValidatorsService, 38 private userValidatorsService: UserValidatorsService,
@@ -226,6 +232,13 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
226 this.checkTranscodingFields() 232 this.checkTranscodingFields()
227 } 233 }
228 234
235 ngAfterViewChecked () {
236 if (!this.initDone) {
237 this.initDone = true
238 this.gotoAnchor()
239 }
240 }
241
229 isTranscodingEnabled () { 242 isTranscodingEnabled () {
230 return this.form.value['transcoding']['enabled'] === true 243 return this.form.value['transcoding']['enabled'] === true
231 } 244 }
@@ -272,6 +285,18 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
272 return this.i18n('No category') 285 return this.i18n('No category')
273 } 286 }
274 287
288 gotoAnchor () {
289 const hashToTab = {
290 'customizations': 'advanced-configuration'
291 }
292 const hash = window.location.hash.replace('#', '')
293
294 if (hash && Object.keys(hashToTab).includes(hash)) {
295 this.tabs.select(hashToTab[hash])
296 setTimeout(() => this.viewportScroller.scrollToAnchor(hash), 100)
297 }
298 }
299
275 private updateForm () { 300 private updateForm () {
276 this.form.patchValue(this.customConfig) 301 this.form.patchValue(this.customConfig)
277 } 302 }
diff --git a/client/src/app/+my-account/my-account-settings/my-account-settings.component.html b/client/src/app/+my-account/my-account-settings/my-account-settings.component.html
index 164afb4ea..87296bc19 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-settings.component.html
+++ b/client/src/app/+my-account/my-account-settings/my-account-settings.component.html
@@ -34,6 +34,7 @@
34 34
35<div class="form-row mt-5"> <!-- notifications grid --> 35<div class="form-row mt-5"> <!-- notifications grid -->
36 <div class="form-group col-12 col-lg-4 col-xl-3"> 36 <div class="form-group col-12 col-lg-4 col-xl-3">
37 <div class="anchor" id="notifications"></div> <!-- notifications anchor -->
37 <div i18n class="account-title">NOTIFICATIONS</div> 38 <div i18n class="account-title">NOTIFICATIONS</div>
38 </div> 39 </div>
39 40
diff --git a/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts b/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts
index e314cdbea..ada98401c 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts
@@ -1,17 +1,18 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit, AfterViewChecked } from '@angular/core'
2import { Notifier } from '@app/core' 2import { Notifier } from '@app/core'
3import { BytesPipe } from 'ngx-pipes' 3import { BytesPipe } from 'ngx-pipes'
4import { AuthService } from '../../core' 4import { AuthService } from '../../core'
5import { User } from '../../shared' 5import { User } from '../../shared'
6import { UserService } from '../../shared/users' 6import { UserService } from '../../shared/users'
7import { I18n } from '@ngx-translate/i18n-polyfill' 7import { I18n } from '@ngx-translate/i18n-polyfill'
8import { ViewportScroller } from '@angular/common'
8 9
9@Component({ 10@Component({
10 selector: 'my-account-settings', 11 selector: 'my-account-settings',
11 templateUrl: './my-account-settings.component.html', 12 templateUrl: './my-account-settings.component.html',
12 styleUrls: [ './my-account-settings.component.scss' ] 13 styleUrls: [ './my-account-settings.component.scss' ]
13}) 14})
14export class MyAccountSettingsComponent implements OnInit { 15export class MyAccountSettingsComponent implements OnInit, AfterViewChecked {
15 user: User = null 16 user: User = null
16 17
17 userVideoQuota = '0' 18 userVideoQuota = '0'
@@ -21,6 +22,7 @@ export class MyAccountSettingsComponent implements OnInit {
21 userVideoQuotaUsedDaily = 0 22 userVideoQuotaUsedDaily = 0
22 23
23 constructor ( 24 constructor (
25 private viewportScroller: ViewportScroller,
24 private userService: UserService, 26 private userService: UserService,
25 private authService: AuthService, 27 private authService: AuthService,
26 private notifier: Notifier, 28 private notifier: Notifier,
@@ -57,6 +59,10 @@ export class MyAccountSettingsComponent implements OnInit {
57 }) 59 })
58 } 60 }
59 61
62 ngAfterViewChecked () {
63 if (window.location.hash) this.viewportScroller.scrollToAnchor(window.location.hash.replace('#', ''))
64 }
65
60 onAvatarChange (formData: FormData) { 66 onAvatarChange (formData: FormData) {
61 this.userService.changeAvatar(formData) 67 this.userService.changeAvatar(formData)
62 .subscribe( 68 .subscribe(
diff --git a/client/src/sass/application.scss b/client/src/sass/application.scss
index f76a82243..89957704b 100644
--- a/client/src/sass/application.scss
+++ b/client/src/sass/application.scss
@@ -246,6 +246,11 @@ table {
246 } 246 }
247} 247}
248 248
249.anchor {
250 position: relative;
251 top: #{-($header-height + 20px)};
252}
253
249@media screen and (max-width: #{map-get($grid-breakpoints, xxl)}) { 254@media screen and (max-width: #{map-get($grid-breakpoints, xxl)}) {
250 .main-col { 255 .main-col {
251 &.expanded { 256 &.expanded {