]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - client/src/app/shared/shared-custom-markup/custom-markup.service.ts
Only display homepage when components are loaded
[github/Chocobozzz/PeerTube.git] / client / src / app / shared / shared-custom-markup / custom-markup.service.ts
index aa5dbe64360be4e63b87915f75179fc69593e309..15da94709eccf7ae59a637ebb965e2accdca956f 100644 (file)
@@ -1,3 +1,4 @@
+import { first } from 'rxjs/operators'
 import { ComponentRef, Injectable } from '@angular/core'
 import { MarkdownService } from '@app/core'
 import {
@@ -19,8 +20,9 @@ import {
   VideoMiniatureMarkupComponent,
   VideosListMarkupComponent
 } from './peertube-custom-tags'
+import { CustomMarkupComponent } from './peertube-custom-tags/shared'
 
-type AngularBuilderFunction = (el: HTMLElement) => ComponentRef<any>
+type AngularBuilderFunction = (el: HTMLElement) => ComponentRef<CustomMarkupComponent>
 type HTMLBuilderFunction = (el: HTMLElement) => HTMLElement
 
 @Injectable()
@@ -45,7 +47,10 @@ export class CustomMarkupService {
     private dynamicElementService: DynamicElementService,
     private markdown: MarkdownService
   ) {
-    this.customMarkdownRenderer = async (text: string) => this.buildElement(text)
+    this.customMarkdownRenderer = (text: string) => {
+      return this.buildElement(text)
+        .then(({ rootElement }) => rootElement)
+    }
   }
 
   getCustomMarkdownRenderer () {
@@ -60,23 +65,30 @@ export class CustomMarkupService {
 
     for (const selector of Object.keys(this.htmlBuilders)) {
       rootElement.querySelectorAll(selector)
-        .forEach((e: HTMLElement) => {
-          try {
-            const element = this.execHTMLBuilder(selector, e)
-            // Insert as first child
-            e.insertBefore(element, e.firstChild)
-          } catch (err) {
-            console.error('Cannot inject component %s.', selector, err)
-          }
-        })
+      .forEach((e: HTMLElement) => {
+        try {
+          const element = this.execHTMLBuilder(selector, e)
+          // Insert as first child
+          e.insertBefore(element, e.firstChild)
+        } catch (err) {
+          console.error('Cannot inject component %s.', selector, err)
+        }
+      })
     }
 
+    const loadedPromises: Promise<boolean>[] = []
+
     for (const selector of Object.keys(this.angularBuilders)) {
       rootElement.querySelectorAll(selector)
         .forEach((e: HTMLElement) => {
           try {
             const component = this.execAngularBuilder(selector, e)
 
+            if (component.instance.loaded) {
+              const p = component.instance.loaded.pipe(first()).toPromise()
+              loadedPromises.push(p)
+            }
+
             this.dynamicElementService.injectElement(e, component)
           } catch (err) {
             console.error('Cannot inject component %s.', selector, err)
@@ -84,7 +96,7 @@ export class CustomMarkupService {
         })
     }
 
-    return rootElement
+    return { rootElement, componentsLoaded: Promise.all(loadedPromises) }
   }
 
   private getSupportedTags () {
@@ -138,10 +150,10 @@ export class CustomMarkupService {
     const component = this.dynamicElementService.createElement(ButtonMarkupComponent)
 
     const model = {
-      theme: data.theme,
+      theme: data.theme ?? 'primary',
       href: data.href,
       label: data.label,
-      blankTarget: this.buildBoolean(data.blankTarget)
+      blankTarget: this.buildBoolean(data.blankTarget) ?? false
     }
     this.dynamicElementService.setModel(component, model)
 
@@ -168,11 +180,15 @@ export class CustomMarkupService {
 
     const model = {
       onlyDisplayTitle: this.buildBoolean(data.onlyDisplayTitle) ?? false,
+      maxRows: this.buildNumber(data.maxRows) ?? -1,
+
       sort: data.sort || '-publishedAt',
+      count: this.buildNumber(data.count) || 10,
+
       categoryOneOf: this.buildArrayNumber(data.categoryOneOf) ?? [],
       languageOneOf: this.buildArrayString(data.languageOneOf) ?? [],
-      filter: this.buildBoolean(data.onlyLocal) ? 'local' as VideoFilter : undefined,
-      count: this.buildNumber(data.count) || 10
+
+      filter: this.buildBoolean(data.onlyLocal) ? 'local' as VideoFilter : undefined
     }
 
     this.dynamicElementService.setModel(component, model)
@@ -183,11 +199,16 @@ export class CustomMarkupService {
   private containerBuilder (el: HTMLElement) {
     const data = el.dataset as ContainerMarkupData
 
+    // Move inner HTML in the new element we'll create
+    const content = el.innerHTML
+    el.innerHTML = ''
+
     const root = document.createElement('div')
+    root.innerHTML = content
 
     const layoutClass = data.layout
       ? 'layout-' + data.layout
-      : 'layout-row'
+      : 'layout-column'
 
     root.classList.add('peertube-container', layoutClass)
 
@@ -195,16 +216,23 @@ export class CustomMarkupService {
       root.setAttribute('width', data.width)
     }
 
-    if (data.title) {
-      const titleElement = document.createElement('h4')
-      titleElement.innerText = data.title
-      root.appendChild(titleElement)
-    }
+    if (data.title || data.description) {
+      const headerElement = document.createElement('div')
+      headerElement.classList.add('header')
+
+      if (data.title) {
+        const titleElement = document.createElement('h4')
+        titleElement.innerText = data.title
+        headerElement.appendChild(titleElement)
+      }
+
+      if (data.description) {
+        const descriptionElement = document.createElement('div')
+        descriptionElement.innerText = data.description
+        headerElement.append(descriptionElement)
+      }
 
-    if (data.description) {
-      const descriptionElement = document.createElement('div')
-      descriptionElement.innerText = data.description
-      root.appendChild(descriptionElement)
+      root.insertBefore(headerElement, root.firstChild)
     }
 
     return root