Support mailto links for custom markup
This commit is contained in:
parent
a4927884b2
commit
789ba34931
|
@ -21,7 +21,7 @@
|
|||
|
||||
<div class="anchor" id="administrators-and-sustainability"></div>
|
||||
<a
|
||||
*ngIf="html.administrator || html.maintenanceLifetime || html.businessModel"
|
||||
*ngIf="aboutHTML.administrator || aboutHTML.maintenanceLifetime || aboutHTML.businessModel"
|
||||
class="anchor-link"
|
||||
routerLink="/about/instance"
|
||||
fragment="administrators-and-sustainability"
|
||||
|
@ -33,7 +33,7 @@
|
|||
</h2>
|
||||
</a>
|
||||
|
||||
<div class="block administrator" *ngIf="html.administrator">
|
||||
<div class="block administrator" *ngIf="aboutHTML.administrator">
|
||||
<div class="anchor" id="administrators"></div>
|
||||
<a
|
||||
class="anchor-link"
|
||||
|
@ -44,10 +44,10 @@
|
|||
<h3 i18n class="section-title">Who we are</h3>
|
||||
</a>
|
||||
|
||||
<div [innerHTML]="html.administrator"></div>
|
||||
<div [innerHTML]="aboutHTML.administrator"></div>
|
||||
</div>
|
||||
|
||||
<div class="block creation-reason" *ngIf="html.creationReason">
|
||||
<div class="block creation-reason" *ngIf="aboutHTML.creationReason">
|
||||
<div class="anchor" id="creation-reason"></div>
|
||||
<a
|
||||
class="anchor-link"
|
||||
|
@ -58,10 +58,10 @@
|
|||
<h3 i18n class="section-title">Why we created this instance</h3>
|
||||
</a>
|
||||
|
||||
<div [innerHTML]="html.creationReason"></div>
|
||||
<div [innerHTML]="aboutHTML.creationReason"></div>
|
||||
</div>
|
||||
|
||||
<div class="block maintenance-lifetime" *ngIf="html.maintenanceLifetime">
|
||||
<div class="block maintenance-lifetime" *ngIf="aboutHTML.maintenanceLifetime">
|
||||
<div class="anchor" id="maintenance-lifetime"></div>
|
||||
<a
|
||||
class="anchor-link"
|
||||
|
@ -72,10 +72,10 @@
|
|||
<h3 i18n class="section-title">How long we plan to maintain this instance</h3>
|
||||
</a>
|
||||
|
||||
<div [innerHTML]="html.maintenanceLifetime"></div>
|
||||
<div [innerHTML]="aboutHTML.maintenanceLifetime"></div>
|
||||
</div>
|
||||
|
||||
<div class="block business-model" *ngIf="html.businessModel">
|
||||
<div class="block business-model" *ngIf="aboutHTML.businessModel">
|
||||
<div class="anchor" id="business-model"></div>
|
||||
<a
|
||||
class="anchor-link"
|
||||
|
@ -86,12 +86,12 @@
|
|||
<h3 i18n class="section-title">How we will pay for keeping our instance running</h3>
|
||||
</a>
|
||||
|
||||
<div [innerHTML]="html.businessModel"></div>
|
||||
<div [innerHTML]="aboutHTML.businessModel"></div>
|
||||
</div>
|
||||
|
||||
<div class="anchor" id="information"></div>
|
||||
<a
|
||||
*ngIf="descriptionContent"
|
||||
*ngIf="descriptionElement"
|
||||
class="anchor-link"
|
||||
routerLink="/about/instance"
|
||||
fragment="information"
|
||||
|
@ -113,13 +113,13 @@
|
|||
<h3 i18n class="section-title">Description</h3>
|
||||
</a>
|
||||
|
||||
<my-custom-markup-container [content]="descriptionContent"></my-custom-markup-container>
|
||||
<my-custom-markup-container [content]="descriptionElement"></my-custom-markup-container>
|
||||
</div>
|
||||
|
||||
<div myPluginSelector pluginSelectorId="about-instance-moderation">
|
||||
<div class="anchor" id="moderation"></div>
|
||||
<a
|
||||
*ngIf="html.moderationInformation || html.codeOfConduct || html.terms"
|
||||
*ngIf="aboutHTML.moderationInformation || aboutHTML.codeOfConduct || aboutHTML.terms"
|
||||
class="anchor-link"
|
||||
routerLink="/about/instance"
|
||||
fragment="moderation"
|
||||
|
@ -130,7 +130,7 @@
|
|||
</h2>
|
||||
</a>
|
||||
|
||||
<div class="block moderation-information" *ngIf="html.moderationInformation">
|
||||
<div class="block moderation-information" *ngIf="aboutHTML.moderationInformation">
|
||||
<div class="anchor" id="moderation-information"></div>
|
||||
<a
|
||||
class="anchor-link"
|
||||
|
@ -141,10 +141,10 @@
|
|||
<h3 i18n class="section-title">Moderation information</h3>
|
||||
</a>
|
||||
|
||||
<div [innerHTML]="html.moderationInformation"></div>
|
||||
<div [innerHTML]="aboutHTML.moderationInformation"></div>
|
||||
</div>
|
||||
|
||||
<div class="block code-of-conduct" *ngIf="html.codeOfConduct">
|
||||
<div class="block code-of-conduct" *ngIf="aboutHTML.codeOfConduct">
|
||||
<div class="anchor" id="code-of-conduct"></div>
|
||||
<a
|
||||
class="anchor-link"
|
||||
|
@ -155,7 +155,7 @@
|
|||
<h3 i18n class="section-title">Code of conduct</h3>
|
||||
</a>
|
||||
|
||||
<div [innerHTML]="html.codeOfConduct"></div>
|
||||
<div [innerHTML]="aboutHTML.codeOfConduct"></div>
|
||||
</div>
|
||||
|
||||
<div class="block terms">
|
||||
|
@ -169,14 +169,14 @@
|
|||
<h3 i18n class="section-title">Terms</h3>
|
||||
</a>
|
||||
|
||||
<div [innerHTML]="html.terms"></div>
|
||||
<div [innerHTML]="aboutHTML.terms"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div myPluginSelector pluginSelectorId="about-instance-other-information">
|
||||
<div class="anchor" id="other-information"></div>
|
||||
<a
|
||||
*ngIf="html.hardwareInformation"
|
||||
*ngIf="aboutHTML.hardwareInformation"
|
||||
class="anchor-link"
|
||||
routerLink="/about/instance"
|
||||
fragment="other-information"
|
||||
|
@ -187,7 +187,7 @@
|
|||
</h2>
|
||||
</a>
|
||||
|
||||
<div class="block hardware-information" *ngIf="html.hardwareInformation">
|
||||
<div class="block hardware-information" *ngIf="aboutHTML.hardwareInformation">
|
||||
<div class="anchor" id="hardware-information"></div>
|
||||
<a
|
||||
class="anchor-link"
|
||||
|
@ -198,7 +198,7 @@
|
|||
<h3 i18n class="section-title">Hardware information</h3>
|
||||
</a>
|
||||
|
||||
<div [innerHTML]="html.hardwareInformation"></div>
|
||||
<div [innerHTML]="aboutHTML.hardwareInformation"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,7 @@ import { ViewportScroller } from '@angular/common'
|
|||
import { AfterViewChecked, Component, ElementRef, OnInit, ViewChild } from '@angular/core'
|
||||
import { ActivatedRoute } from '@angular/router'
|
||||
import { Notifier, ServerService } from '@app/core'
|
||||
import { InstanceService } from '@app/shared/shared-instance'
|
||||
import { AboutHTML } from '@app/shared/shared-instance'
|
||||
import { copyToClipboard } from '@root-helpers/utils'
|
||||
import { HTMLServerConfig } from '@shared/models/server'
|
||||
import { ResolverData } from './about-instance.resolver'
|
||||
|
@ -17,22 +17,12 @@ export class AboutInstanceComponent implements OnInit, AfterViewChecked {
|
|||
@ViewChild('descriptionWrapper') descriptionWrapper: ElementRef<HTMLInputElement>
|
||||
@ViewChild('contactAdminModal', { static: true }) contactAdminModal: ContactAdminModalComponent
|
||||
|
||||
shortDescription = ''
|
||||
descriptionContent: string
|
||||
|
||||
html = {
|
||||
terms: '',
|
||||
codeOfConduct: '',
|
||||
moderationInformation: '',
|
||||
administrator: '',
|
||||
creationReason: '',
|
||||
maintenanceLifetime: '',
|
||||
businessModel: '',
|
||||
hardwareInformation: ''
|
||||
}
|
||||
aboutHTML: AboutHTML
|
||||
descriptionElement: HTMLDivElement
|
||||
|
||||
languages: string[] = []
|
||||
categories: string[] = []
|
||||
shortDescription = ''
|
||||
|
||||
initialized = false
|
||||
|
||||
|
@ -44,8 +34,7 @@ export class AboutInstanceComponent implements OnInit, AfterViewChecked {
|
|||
private viewportScroller: ViewportScroller,
|
||||
private route: ActivatedRoute,
|
||||
private notifier: Notifier,
|
||||
private serverService: ServerService,
|
||||
private instanceService: InstanceService
|
||||
private serverService: ServerService
|
||||
) {}
|
||||
|
||||
get instanceName () {
|
||||
|
@ -60,8 +49,16 @@ export class AboutInstanceComponent implements OnInit, AfterViewChecked {
|
|||
return this.serverConfig.instance.isNSFW
|
||||
}
|
||||
|
||||
async ngOnInit () {
|
||||
const { about, languages, categories }: ResolverData = this.route.snapshot.data.instanceData
|
||||
ngOnInit () {
|
||||
const { about, languages, categories, aboutHTML, descriptionElement }: ResolverData = this.route.snapshot.data.instanceData
|
||||
|
||||
this.aboutHTML = aboutHTML
|
||||
this.descriptionElement = descriptionElement
|
||||
|
||||
this.languages = languages
|
||||
this.categories = categories
|
||||
|
||||
this.shortDescription = about.instance.shortDescription
|
||||
|
||||
this.serverConfig = this.serverService.getHTMLConfig()
|
||||
|
||||
|
@ -73,14 +70,6 @@ export class AboutInstanceComponent implements OnInit, AfterViewChecked {
|
|||
this.contactAdminModal.show(prefill)
|
||||
})
|
||||
|
||||
this.languages = languages
|
||||
this.categories = categories
|
||||
|
||||
this.shortDescription = about.instance.shortDescription
|
||||
this.descriptionContent = about.instance.description
|
||||
|
||||
this.html = await this.instanceService.buildHtml(about)
|
||||
|
||||
this.initialized = true
|
||||
}
|
||||
|
||||
|
|
|
@ -2,16 +2,25 @@ import { forkJoin } from 'rxjs'
|
|||
import { map, switchMap } from 'rxjs/operators'
|
||||
import { Injectable } from '@angular/core'
|
||||
import { Resolve } from '@angular/router'
|
||||
import { InstanceService } from '@app/shared/shared-instance'
|
||||
import { CustomMarkupService } from '@app/shared/shared-custom-markup'
|
||||
import { AboutHTML, InstanceService } from '@app/shared/shared-instance'
|
||||
import { About } from '@shared/models/server'
|
||||
|
||||
export type ResolverData = { about: About, languages: string[], categories: string[] }
|
||||
export type ResolverData = {
|
||||
about: About
|
||||
languages: string[]
|
||||
categories: string[]
|
||||
aboutHTML: AboutHTML
|
||||
descriptionElement: HTMLDivElement
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class AboutInstanceResolver implements Resolve<any> {
|
||||
|
||||
constructor (
|
||||
private instanceService: InstanceService
|
||||
private instanceService: InstanceService,
|
||||
private customMarkupService: CustomMarkupService
|
||||
|
||||
) {}
|
||||
|
||||
resolve () {
|
||||
|
@ -19,9 +28,15 @@ export class AboutInstanceResolver implements Resolve<any> {
|
|||
.pipe(
|
||||
switchMap(about => {
|
||||
return forkJoin([
|
||||
Promise.resolve(about),
|
||||
this.instanceService.buildTranslatedLanguages(about),
|
||||
this.instanceService.buildTranslatedCategories(about)
|
||||
]).pipe(map(([ languages, categories ]) => ({ about, languages, categories }) as ResolverData))
|
||||
this.instanceService.buildTranslatedCategories(about),
|
||||
this.instanceService.buildHtml(about),
|
||||
this.customMarkupService.buildElement(about.instance.description)
|
||||
])
|
||||
}),
|
||||
map(([ about, languages, categories, aboutHTML, { rootElement } ]) => {
|
||||
return { about, languages, categories, aboutHTML, descriptionElement: rootElement } as ResolverData
|
||||
})
|
||||
)
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@ import { CustomMarkupService } from './custom-markup.service'
|
|||
templateUrl: './custom-markup-container.component.html'
|
||||
})
|
||||
export class CustomMarkupContainerComponent implements OnChanges {
|
||||
@ViewChild('contentWrapper') contentWrapper: ElementRef<HTMLInputElement>
|
||||
@ViewChild('contentWrapper', { static: true }) contentWrapper: ElementRef<HTMLInputElement>
|
||||
|
||||
@Input() content: string
|
||||
@Input() content: string | HTMLDivElement
|
||||
|
||||
displayed = false
|
||||
|
||||
|
@ -17,17 +17,23 @@ export class CustomMarkupContainerComponent implements OnChanges {
|
|||
) { }
|
||||
|
||||
async ngOnChanges () {
|
||||
await this.buildElement()
|
||||
await this.rebuild()
|
||||
}
|
||||
|
||||
private async buildElement () {
|
||||
if (!this.content) return
|
||||
private async rebuild () {
|
||||
if (this.content instanceof HTMLDivElement) {
|
||||
return this.loadElement(this.content)
|
||||
}
|
||||
|
||||
const { rootElement, componentsLoaded } = await this.customMarkupService.buildElement(this.content)
|
||||
this.contentWrapper.nativeElement.appendChild(rootElement)
|
||||
|
||||
await componentsLoaded
|
||||
|
||||
return this.loadElement(rootElement)
|
||||
}
|
||||
|
||||
private loadElement (el: HTMLDivElement) {
|
||||
this.contentWrapper.nativeElement.appendChild(el)
|
||||
|
||||
this.displayed = true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,11 @@ import { peertubeTranslate } from '@shared/core-utils/i18n'
|
|||
import { About } from '@shared/models'
|
||||
import { environment } from '../../../environments/environment'
|
||||
|
||||
export type AboutHTML = Pick<About['instance'],
|
||||
'terms' | 'codeOfConduct' | 'moderationInformation' | 'administrator' | 'creationReason' |
|
||||
'maintenanceLifetime' | 'businessModel' | 'hardwareInformation'
|
||||
>
|
||||
|
||||
@Injectable()
|
||||
export class InstanceService {
|
||||
private static BASE_CONFIG_URL = environment.apiUrl + '/api/v1/config'
|
||||
|
@ -39,7 +44,7 @@ export class InstanceService {
|
|||
}
|
||||
|
||||
async buildHtml (about: About) {
|
||||
const html = {
|
||||
const html: AboutHTML = {
|
||||
terms: '',
|
||||
codeOfConduct: '',
|
||||
moderationInformation: '',
|
||||
|
|
Loading…
Reference in New Issue