diff options
author | Chocobozzz <me@florianbigard.com> | 2021-06-15 11:57:15 +0200 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2021-06-15 14:15:10 +0200 |
commit | 5c16e6bc9776ce706bafb198c1c14936674794d5 (patch) | |
tree | f0ff2273f4a7ad1fc7fc92c9f9e360ef86eec204 /client | |
parent | 089cfa65697b60e6ff109f9bf517458908b7c855 (diff) | |
download | PeerTube-5c16e6bc9776ce706bafb198c1c14936674794d5.tar.gz PeerTube-5c16e6bc9776ce706bafb198c1c14936674794d5.tar.zst PeerTube-5c16e6bc9776ce706bafb198c1c14936674794d5.zip |
Cleanup contact form with URL
Parent component still have the responsability to explicitely open the
modal
Rely on data router param to open or not the modal
Diffstat (limited to 'client')
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 @@ | |||
1 | import { ViewportScroller } from '@angular/common' | 1 | import { ViewportScroller } from '@angular/common' |
2 | import { AfterViewChecked, Component, ElementRef, OnInit, ViewChild } from '@angular/core' | 2 | import { AfterViewChecked, Component, ElementRef, OnInit, ViewChild } from '@angular/core' |
3 | import { ActivatedRoute } from '@angular/router' | 3 | import { ActivatedRoute } from '@angular/router' |
4 | import { ContactAdminModalComponent } from '@app/+about/about-instance/contact-admin-modal.component' | ||
5 | import { Notifier, ServerService } from '@app/core' | 4 | import { Notifier, ServerService } from '@app/core' |
6 | import { CustomMarkupService } from '@app/shared/shared-custom-markup' | ||
7 | import { InstanceService } from '@app/shared/shared-instance' | 5 | import { InstanceService } from '@app/shared/shared-instance' |
8 | import { About, HTMLServerConfig, ServerConfig } from '@shared/models' | 6 | import { copyToClipboard } from '@root-helpers/utils' |
9 | import { copyToClipboard } from '../../../root-helpers/utils' | 7 | import { HTMLServerConfig } from '@shared/models/server' |
10 | import { ResolverData } from './about-instance.resolver' | 8 | import { ResolverData } from './about-instance.resolver' |
9 | import { 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 | }) |
17 | export class AboutInstanceComponent implements OnInit, AfterViewChecked { | 16 | export 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 | |||
4 | input[type=text] { | 8 | input[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 | ||
13 | textarea { | 14 | textarea { |
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 @@ | |||
1 | import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core' | 1 | import { Component, OnInit, ViewChild } from '@angular/core' |
2 | import { ActivatedRoute, Router, NavigationEnd } from '@angular/router' | 2 | import { Router } from '@angular/router' |
3 | import { Subject } from 'rxjs' | ||
4 | import { takeUntil, filter } from 'rxjs/operators' | ||
5 | import { Notifier, ServerService } from '@app/core' | 3 | import { Notifier, ServerService } from '@app/core' |
6 | import { | 4 | import { |
7 | BODY_VALIDATOR, | 5 | BODY_VALIDATOR, |
@@ -16,30 +14,31 @@ import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' | |||
16 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | 14 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' |
17 | import { HTMLServerConfig } from '@shared/models' | 15 | import { HTMLServerConfig } from '@shared/models' |
18 | 16 | ||
17 | type 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 | }) |
24 | export class ContactAdminModalComponent extends FormReactive implements OnInit, OnDestroy { | 27 | export 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 | } |