aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--client/src/app/+about/about-instance/about-instance.component.html4
-rw-r--r--client/src/app/+about/about-instance/about-instance.component.scss11
-rw-r--r--client/src/app/+about/about-instance/about-instance.component.ts16
-rw-r--r--client/src/app/+about/about-instance/contact-admin-modal.component.html4
-rw-r--r--client/src/app/+about/about-instance/contact-admin-modal.component.scss15
-rw-r--r--client/src/app/+about/about-instance/contact-admin-modal.component.ts76
-rw-r--r--client/src/app/+about/about-routing.module.ts19
-rw-r--r--client/src/sass/include/_mixins.scss2
8 files changed, 61 insertions, 86 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 a42bda845..436d486ab 100644
--- a/client/src/app/+about/about-instance/about-instance.component.html
+++ b/client/src/app/+about/about-instance/about-instance.component.html
@@ -4,7 +4,7 @@
4 <div class="about-instance-title"> 4 <div class="about-instance-title">
5 <h1 i18n class="title">About {{ instanceName }}</h1> 5 <h1 i18n class="title">About {{ instanceName }}</h1>
6 6
7 <a routerLink="contact" i18n *ngIf="isContactFormEnabled" class="contact-admin">Contact administrator</a> 7 <a routerLink="/about/contact" i18n *ngIf="isContactFormEnabled" class="contact-admin">Contact administrator</a>
8 </div> 8 </div>
9 9
10 <div class="instance-badges" *ngIf="categories.length !== 0 || languages.length !== 0"> 10 <div class="instance-badges" *ngIf="categories.length !== 0 || languages.length !== 0">
@@ -218,4 +218,4 @@
218 </div> 218 </div>
219</div> 219</div>
220 220
221<my-contact-admin-modal></my-contact-admin-modal> 221<my-contact-admin-modal #contactAdminModal></my-contact-admin-modal>
diff --git a/client/src/app/+about/about-instance/about-instance.component.scss b/client/src/app/+about/about-instance/about-instance.component.scss
index b7bf10995..6bbb66a58 100644
--- a/client/src/app/+about/about-instance/about-instance.component.scss
+++ b/client/src/app/+about/about-instance/about-instance.component.scss
@@ -11,15 +11,10 @@
11 } 11 }
12 12
13 .contact-admin { 13 .contact-admin {
14 @include peertube-button; 14 @include peertube-button-link;
15 @include orange-button; 15 @include orange-button;
16 16
17 height: fit-content; 17 height: fit-content;
18
19 &:hover,
20 &:active {
21 text-decoration: none;
22 }
23 } 18 }
24} 19}
25 20
@@ -59,6 +54,10 @@
59 font-size: 15px; 54 font-size: 15px;
60} 55}
61 56
57.short-description {
58 margin-top: 10px;
59}
60
62.short-description .dedicated-to-nsfw { 61.short-description .dedicated-to-nsfw {
63 margin-top: 20px; 62 margin-top: 20px;
64 font-weight: $font-semibold; 63 font-weight: $font-semibold;
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 ffb4294ab..f86df5b67 100644
--- a/client/src/app/+about/about-instance/about-instance.component.ts
+++ b/client/src/app/+about/about-instance/about-instance.component.ts
@@ -1,13 +1,12 @@
1import { ViewportScroller } from '@angular/common' 1import { ViewportScroller } from '@angular/common'
2import { AfterViewChecked, Component, ElementRef, OnInit, ViewChild } from '@angular/core' 2import { AfterViewChecked, Component, ElementRef, OnInit, ViewChild } from '@angular/core'
3import { ActivatedRoute } from '@angular/router' 3import { ActivatedRoute } from '@angular/router'
4import { ContactAdminModalComponent } from '@app/+about/about-instance/contact-admin-modal.component'
5import { Notifier, ServerService } from '@app/core' 4import { Notifier, ServerService } from '@app/core'
6import { CustomMarkupService } from '@app/shared/shared-custom-markup'
7import { InstanceService } from '@app/shared/shared-instance' 5import { InstanceService } from '@app/shared/shared-instance'
8import { About, HTMLServerConfig, ServerConfig } from '@shared/models' 6import { copyToClipboard } from '@root-helpers/utils'
9import { copyToClipboard } from '../../../root-helpers/utils' 7import { HTMLServerConfig } from '@shared/models/server'
10import { ResolverData } from './about-instance.resolver' 8import { ResolverData } from './about-instance.resolver'
9import { ContactAdminModalComponent } from './contact-admin-modal.component'
11 10
12@Component({ 11@Component({
13 selector: 'my-about-instance', 12 selector: 'my-about-instance',
@@ -16,6 +15,7 @@ import { ResolverData } from './about-instance.resolver'
16}) 15})
17export class AboutInstanceComponent implements OnInit, AfterViewChecked { 16export class AboutInstanceComponent implements OnInit, AfterViewChecked {
18 @ViewChild('descriptionWrapper') descriptionWrapper: ElementRef<HTMLInputElement> 17 @ViewChild('descriptionWrapper') descriptionWrapper: ElementRef<HTMLInputElement>
18 @ViewChild('contactAdminModal', { static: true }) contactAdminModal: ContactAdminModalComponent
19 19
20 shortDescription = '' 20 shortDescription = ''
21 descriptionContent: string 21 descriptionContent: string
@@ -65,6 +65,14 @@ export class AboutInstanceComponent implements OnInit, AfterViewChecked {
65 65
66 this.serverConfig = this.serverService.getHTMLConfig() 66 this.serverConfig = this.serverService.getHTMLConfig()
67 67
68 this.route.data.subscribe(data => {
69 if (!data?.isContact) return
70
71 const prefill = this.route.snapshot.queryParams
72
73 this.contactAdminModal.show(prefill)
74 })
75
68 this.languages = languages 76 this.languages = languages
69 this.categories = categories 77 this.categories = categories
70 78
diff --git a/client/src/app/+about/about-instance/contact-admin-modal.component.html b/client/src/app/+about/about-instance/contact-admin-modal.component.html
index 343e5d649..8b6b707af 100644
--- a/client/src/app/+about/about-instance/contact-admin-modal.component.html
+++ b/client/src/app/+about/about-instance/contact-admin-modal.component.html
@@ -6,7 +6,7 @@
6 6
7 <div class="modal-body"> 7 <div class="modal-body">
8 8
9 <form novalidate [formGroup]="form" (ngSubmit)="sendForm()"> 9 <form *ngIf="isContactFormEnabled()" novalidate [formGroup]="form" (ngSubmit)="sendForm()">
10 <div class="form-group"> 10 <div class="form-group">
11 <label i18n for="fromName">Your name</label> 11 <label i18n for="fromName">Your name</label>
12 <input 12 <input
@@ -53,5 +53,7 @@
53 </div> 53 </div>
54 </form> 54 </form>
55 55
56 <div *ngIf="!isContactFormEnabled()" class="alert alert-error" i18n>The contact form is not enabled on this instance.</div>
57
56 </div> 58 </div>
57</ng-template> 59</ng-template>
diff --git a/client/src/app/+about/about-instance/contact-admin-modal.component.scss b/client/src/app/+about/about-instance/contact-admin-modal.component.scss
index cd3cf85dd..cc75e8279 100644
--- a/client/src/app/+about/about-instance/contact-admin-modal.component.scss
+++ b/client/src/app/+about/about-instance/contact-admin-modal.component.scss
@@ -1,21 +1,16 @@
1@import 'variables'; 1@import 'variables';
2@import 'mixins'; 2@import 'mixins';
3 3
4.modal-body {
5 text-align: left;
6}
7
4input[type=text] { 8input[type=text] {
5 @include peertube-input-text(340px); 9 @include peertube-input-text(340px);
6 display: block;
7 10
8 @media screen and (max-width: #{map-get($container-max-widths, sm)}) { 11 display: block;
9 width: 100%;
10 }
11} 12}
12 13
13textarea { 14textarea {
14 @include peertube-textarea(100%, 200px); 15 @include peertube-textarea(100%, 200px);
15} 16}
16
17@media screen and (max-width: breakpoint(md)) {
18 .modal-body {
19 text-align: left;
20 }
21}
diff --git a/client/src/app/+about/about-instance/contact-admin-modal.component.ts b/client/src/app/+about/about-instance/contact-admin-modal.component.ts
index 32812d9e0..a528faa20 100644
--- a/client/src/app/+about/about-instance/contact-admin-modal.component.ts
+++ b/client/src/app/+about/about-instance/contact-admin-modal.component.ts
@@ -1,7 +1,5 @@
1import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core' 1import { Component, OnInit, ViewChild } from '@angular/core'
2import { ActivatedRoute, Router, NavigationEnd } from '@angular/router' 2import { Router } from '@angular/router'
3import { Subject } from 'rxjs'
4import { takeUntil, filter } from 'rxjs/operators'
5import { Notifier, ServerService } from '@app/core' 3import { Notifier, ServerService } from '@app/core'
6import { 4import {
7 BODY_VALIDATOR, 5 BODY_VALIDATOR,
@@ -16,30 +14,31 @@ import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
16import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' 14import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
17import { HTMLServerConfig } from '@shared/models' 15import { HTMLServerConfig } from '@shared/models'
18 16
17type Prefill = {
18 subject?: string
19 body?: string
20}
21
19@Component({ 22@Component({
20 selector: 'my-contact-admin-modal', 23 selector: 'my-contact-admin-modal',
21 templateUrl: './contact-admin-modal.component.html', 24 templateUrl: './contact-admin-modal.component.html',
22 styleUrls: [ './contact-admin-modal.component.scss' ] 25 styleUrls: [ './contact-admin-modal.component.scss' ]
23}) 26})
24export class ContactAdminModalComponent extends FormReactive implements OnInit, OnDestroy { 27export class ContactAdminModalComponent extends FormReactive implements OnInit {
25 @ViewChild('modal', { static: true }) modal: NgbModal 28 @ViewChild('modal', { static: true }) modal: NgbModal
26 29
27 error: string 30 error: string
28 destroy = new Subject<any>()
29
30 subject: string
31 31
32 private openedModal: NgbModalRef 32 private openedModal: NgbModalRef
33 private serverConfig: HTMLServerConfig 33 private serverConfig: HTMLServerConfig
34 34
35 constructor ( 35 constructor (
36 protected formValidatorService: FormValidatorService, 36 protected formValidatorService: FormValidatorService,
37 private router: Router,
37 private modalService: NgbModal, 38 private modalService: NgbModal,
38 private instanceService: InstanceService, 39 private instanceService: InstanceService,
39 private serverService: ServerService, 40 private serverService: ServerService,
40 private notifier: Notifier, 41 private notifier: Notifier
41 private route: ActivatedRoute,
42 private router: Router
43 ) { 42 ) {
44 super() 43 super()
45 } 44 }
@@ -48,10 +47,6 @@ export class ContactAdminModalComponent extends FormReactive implements OnInit,
48 return this.serverConfig.instance.name 47 return this.serverConfig.instance.name
49 } 48 }
50 49
51 get isContactFormEnabled () {
52 return this.serverConfig.email.enabled && this.serverConfig.contactForm.enabled
53 }
54
55 ngOnInit () { 50 ngOnInit () {
56 this.serverConfig = this.serverService.getHTMLConfig() 51 this.serverConfig = this.serverService.getHTMLConfig()
57 52
@@ -61,46 +56,17 @@ export class ContactAdminModalComponent extends FormReactive implements OnInit,
61 subject: SUBJECT_VALIDATOR, 56 subject: SUBJECT_VALIDATOR,
62 body: BODY_VALIDATOR 57 body: BODY_VALIDATOR
63 }) 58 })
64
65 // Direct access
66 if (/^\/about\/instance\/contact/.test(this.router.url)) {
67 this.show()
68 this.prefillForm()
69 }
70
71 // Router access
72 this.router.events
73 .pipe(
74 takeUntil(this.destroy),
75 filter(event => event instanceof NavigationEnd)
76 )
77 .subscribe((event: NavigationEnd) => {
78 if (/^\/about\/instance\/contact/.test(event.url)) {
79 this.show()
80 this.prefillForm()
81 }
82 })
83 } 59 }
84 60
85 ngOnDestroy () { 61 isContactFormEnabled () {
86 this.destroy.next() 62 return this.serverConfig.email.enabled && this.serverConfig.contactForm.enabled
87 } 63 }
88 64
89 show () { 65 show (prefill: Prefill = {}) {
90 // If contactForm not enabled redirect to 404
91 if (!this.isContactFormEnabled) {
92 return this.router.navigate([ '/404' ], { state: { type: 'other', obj: { status: 404 } }, skipLocationChange: true })
93 }
94
95 // Open modal
96 this.openedModal = this.modalService.open(this.modal, { centered: true, keyboard: false }) 66 this.openedModal = this.modalService.open(this.modal, { centered: true, keyboard: false })
97 67
98 // Go back to /about/instance after the modal is closed 68 this.openedModal.shown.subscribe(() => this.prefillForm(prefill))
99 this.openedModal.result.then(() => { 69 this.openedModal.result.finally(() => this.router.navigateByUrl('/about/instance'))
100 this.router.navigateByUrl('/about/instance')
101 }, () => {
102 this.router.navigateByUrl('/about/instance')
103 })
104 } 70 }
105 71
106 hide () { 72 hide () {
@@ -132,15 +98,13 @@ export class ContactAdminModalComponent extends FormReactive implements OnInit,
132 ) 98 )
133 } 99 }
134 100
135 private prefillForm () { 101 private prefillForm (prefill: Prefill) {
136 const { subject, body } = this.route.snapshot.queryParams 102 if (prefill.subject) {
137 103 this.form.get('subject').setValue(prefill.subject)
138 if (subject) {
139 this.form.get('subject').setValue(subject)
140 } 104 }
141 105
142 if (body) { 106 if (prefill.body) {
143 this.form.get('body').setValue(body) 107 this.form.get('body').setValue(prefill.body)
144 } 108 }
145 } 109 }
146} 110}
diff --git a/client/src/app/+about/about-routing.module.ts b/client/src/app/+about/about-routing.module.ts
index c810ca272..3974231e3 100644
--- a/client/src/app/+about/about-routing.module.ts
+++ b/client/src/app/+about/about-routing.module.ts
@@ -27,13 +27,20 @@ const aboutRoutes: Routes = [
27 }, 27 },
28 resolve: { 28 resolve: {
29 instanceData: AboutInstanceResolver 29 instanceData: AboutInstanceResolver
30 }
31 },
32 {
33 path: 'contact',
34 component: AboutInstanceComponent,
35 data: {
36 meta: {
37 title: $localize`Contact`
38 },
39 isContact: true
30 }, 40 },
31 children: [ 41 resolve: {
32 { 42 instanceData: AboutInstanceResolver
33 path: 'contact', 43 }
34 component: ContactAdminModalComponent
35 }
36 ]
37 }, 44 },
38 { 45 {
39 path: 'peertube', 46 path: 'peertube',
diff --git a/client/src/sass/include/_mixins.scss b/client/src/sass/include/_mixins.scss
index 0822e0ca6..a835381d6 100644
--- a/client/src/sass/include/_mixins.scss
+++ b/client/src/sass/include/_mixins.scss
@@ -102,7 +102,7 @@
102 opacity: 0.7; 102 opacity: 0.7;
103 } 103 }
104 104
105 @media screen and (max-width: $width) { 105 @media screen and (max-width: calc(#{$width} + 40px)) {
106 width: 100%; 106 width: 100%;
107 } 107 }
108} 108}