Only display homepage when components are loaded
This commit is contained in:
parent
76b8d72e32
commit
0ca454e3bd
11 changed files with 90 additions and 32 deletions
|
@ -1 +1 @@
|
|||
<div class="custom-markup-container" #contentWrapper></div>
|
||||
<div [hidden]="!displayed" class="custom-markup-container" #contentWrapper></div>
|
||||
|
|
|
@ -10,6 +10,8 @@ export class CustomMarkupContainerComponent implements OnChanges {
|
|||
|
||||
@Input() content: string
|
||||
|
||||
displayed = false
|
||||
|
||||
constructor (
|
||||
private customMarkupService: CustomMarkupService
|
||||
) { }
|
||||
|
@ -19,8 +21,13 @@ export class CustomMarkupContainerComponent implements OnChanges {
|
|||
}
|
||||
|
||||
private async buildElement () {
|
||||
const element = await this.customMarkupService.buildElement(this.content)
|
||||
this.contentWrapper.nativeElement.appendChild(element)
|
||||
}
|
||||
if (!this.content) return
|
||||
|
||||
const { rootElement, componentsLoaded } = await this.customMarkupService.buildElement(this.content)
|
||||
this.contentWrapper.nativeElement.appendChild(rootElement)
|
||||
|
||||
await componentsLoaded
|
||||
|
||||
this.displayed = true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 () {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { Component, Input } from '@angular/core'
|
||||
import { VideoChannel } from '../../shared-main'
|
||||
import { CustomMarkupComponent } from './shared'
|
||||
|
||||
/*
|
||||
* Markup component that creates a button
|
||||
|
@ -10,13 +11,14 @@ import { VideoChannel } from '../../shared-main'
|
|||
templateUrl: 'button-markup.component.html',
|
||||
styleUrls: [ 'button-markup.component.scss' ]
|
||||
})
|
||||
export class ButtonMarkupComponent {
|
||||
export class ButtonMarkupComponent implements CustomMarkupComponent {
|
||||
@Input() theme: 'primary' | 'secondary'
|
||||
@Input() href: string
|
||||
@Input() label: string
|
||||
@Input() blankTarget?: boolean
|
||||
|
||||
channel: VideoChannel
|
||||
loaded: undefined
|
||||
|
||||
getTarget () {
|
||||
if (this.blankTarget === true) return '_blank'
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { map, switchMap } from 'rxjs/operators'
|
||||
import { Component, Input, OnInit } from '@angular/core'
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
|
||||
import { MarkdownService, UserService } from '@app/core'
|
||||
import { Video, VideoSortField } from '@shared/models/videos'
|
||||
import { VideoChannel, VideoChannelService, VideoService } from '../../shared-main'
|
||||
import { CustomMarkupComponent } from './shared'
|
||||
|
||||
/*
|
||||
* Markup component that creates a channel miniature only
|
||||
|
@ -13,11 +14,13 @@ import { VideoChannel, VideoChannelService, VideoService } from '../../shared-ma
|
|||
templateUrl: 'channel-miniature-markup.component.html',
|
||||
styleUrls: [ 'channel-miniature-markup.component.scss' ]
|
||||
})
|
||||
export class ChannelMiniatureMarkupComponent implements OnInit {
|
||||
export class ChannelMiniatureMarkupComponent implements CustomMarkupComponent, OnInit {
|
||||
@Input() name: string
|
||||
@Input() displayLatestVideo: boolean
|
||||
@Input() displayDescription: boolean
|
||||
|
||||
@Output() loaded = new EventEmitter<boolean>()
|
||||
|
||||
channel: VideoChannel
|
||||
descriptionHTML: string
|
||||
totalVideos: number
|
||||
|
@ -61,9 +64,13 @@ export class ChannelMiniatureMarkupComponent implements OnInit {
|
|||
map(user => user.nsfwPolicy),
|
||||
switchMap(nsfwPolicy => this.videoService.getVideoChannelVideos({ ...videoOptions, nsfwPolicy }))
|
||||
)
|
||||
.subscribe(({ total, data }) => {
|
||||
this.totalVideos = total
|
||||
this.video = data[0]
|
||||
.subscribe({
|
||||
next: ({ total, data }) => {
|
||||
this.totalVideos = total
|
||||
this.video = data[0]
|
||||
},
|
||||
|
||||
complete: () => this.loaded.emit(true)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
import { buildPlaylistLink, buildVideoLink, buildVideoOrPlaylistEmbed } from 'src/assets/player/utils'
|
||||
import { environment } from 'src/environments/environment'
|
||||
import { Component, ElementRef, Input, OnInit } from '@angular/core'
|
||||
import { CustomMarkupComponent } from './shared'
|
||||
|
||||
@Component({
|
||||
selector: 'my-embed-markup',
|
||||
template: ''
|
||||
})
|
||||
export class EmbedMarkupComponent implements OnInit {
|
||||
export class EmbedMarkupComponent implements CustomMarkupComponent, OnInit {
|
||||
@Input() uuid: string
|
||||
@Input() type: 'video' | 'playlist' = 'video'
|
||||
|
||||
loaded: undefined
|
||||
|
||||
constructor (private el: ElementRef) { }
|
||||
|
||||
ngOnInit () {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { Component, Input, OnInit } from '@angular/core'
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
|
||||
import { MiniatureDisplayOptions } from '../../shared-video-miniature'
|
||||
import { VideoPlaylist, VideoPlaylistService } from '../../shared-video-playlist'
|
||||
import { CustomMarkupComponent } from './shared'
|
||||
|
||||
/*
|
||||
* Markup component that creates a playlist miniature only
|
||||
|
@ -11,9 +12,11 @@ import { VideoPlaylist, VideoPlaylistService } from '../../shared-video-playlist
|
|||
templateUrl: 'playlist-miniature-markup.component.html',
|
||||
styleUrls: [ 'playlist-miniature-markup.component.scss' ]
|
||||
})
|
||||
export class PlaylistMiniatureMarkupComponent implements OnInit {
|
||||
export class PlaylistMiniatureMarkupComponent implements CustomMarkupComponent, OnInit {
|
||||
@Input() uuid: string
|
||||
|
||||
@Output() loaded = new EventEmitter<boolean>()
|
||||
|
||||
playlist: VideoPlaylist
|
||||
|
||||
displayOptions: MiniatureDisplayOptions = {
|
||||
|
@ -33,6 +36,10 @@ export class PlaylistMiniatureMarkupComponent implements OnInit {
|
|||
|
||||
ngOnInit () {
|
||||
this.playlistService.getVideoPlaylist(this.uuid)
|
||||
.subscribe(playlist => this.playlist = playlist)
|
||||
.subscribe({
|
||||
next: playlist => this.playlist = playlist,
|
||||
|
||||
complete: () => this.loaded.emit(true)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
import { EventEmitter } from '@angular/core'
|
||||
|
||||
export interface CustomMarkupComponent {
|
||||
loaded: EventEmitter<boolean> | undefined
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export * from './custom-markup.component'
|
|
@ -1,7 +1,8 @@
|
|||
import { Component, Input, OnInit } from '@angular/core'
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
|
||||
import { AuthService } from '@app/core'
|
||||
import { Video, VideoService } from '../../shared-main'
|
||||
import { MiniatureDisplayOptions } from '../../shared-video-miniature'
|
||||
import { CustomMarkupComponent } from './shared'
|
||||
|
||||
/*
|
||||
* Markup component that creates a video miniature only
|
||||
|
@ -12,10 +13,12 @@ import { MiniatureDisplayOptions } from '../../shared-video-miniature'
|
|||
templateUrl: 'video-miniature-markup.component.html',
|
||||
styleUrls: [ 'video-miniature-markup.component.scss' ]
|
||||
})
|
||||
export class VideoMiniatureMarkupComponent implements OnInit {
|
||||
export class VideoMiniatureMarkupComponent implements CustomMarkupComponent, OnInit {
|
||||
@Input() uuid: string
|
||||
@Input() onlyDisplayTitle: boolean
|
||||
|
||||
@Output() loaded = new EventEmitter<boolean>()
|
||||
|
||||
video: Video
|
||||
|
||||
displayOptions: MiniatureDisplayOptions = {
|
||||
|
@ -46,6 +49,10 @@ export class VideoMiniatureMarkupComponent implements OnInit {
|
|||
}
|
||||
|
||||
this.videoService.getVideo({ videoId: this.uuid })
|
||||
.subscribe(video => this.video = video)
|
||||
.subscribe({
|
||||
next: video => this.video = video,
|
||||
|
||||
complete: () => this.loaded.emit(true)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { Component, Input, OnInit } from '@angular/core'
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
|
||||
import { AuthService } from '@app/core'
|
||||
import { VideoFilter, VideoSortField } from '@shared/models'
|
||||
import { Video, VideoService } from '../../shared-main'
|
||||
import { MiniatureDisplayOptions } from '../../shared-video-miniature'
|
||||
import { CustomMarkupComponent } from './shared'
|
||||
|
||||
/*
|
||||
* Markup component list videos depending on criterias
|
||||
|
@ -13,7 +14,7 @@ import { MiniatureDisplayOptions } from '../../shared-video-miniature'
|
|||
templateUrl: 'videos-list-markup.component.html',
|
||||
styleUrls: [ 'videos-list-markup.component.scss' ]
|
||||
})
|
||||
export class VideosListMarkupComponent implements OnInit {
|
||||
export class VideosListMarkupComponent implements CustomMarkupComponent, OnInit {
|
||||
@Input() sort: string
|
||||
@Input() categoryOneOf: number[]
|
||||
@Input() languageOneOf: string[]
|
||||
|
@ -22,6 +23,8 @@ export class VideosListMarkupComponent implements OnInit {
|
|||
@Input() filter: VideoFilter
|
||||
@Input() maxRows: number
|
||||
|
||||
@Output() loaded = new EventEmitter<boolean>()
|
||||
|
||||
videos: Video[]
|
||||
|
||||
displayOptions: MiniatureDisplayOptions = {
|
||||
|
@ -73,6 +76,10 @@ export class VideosListMarkupComponent implements OnInit {
|
|||
}
|
||||
|
||||
this.videoService.getVideos(options)
|
||||
.subscribe(({ data }) => this.videos = data)
|
||||
.subscribe({
|
||||
next: ({ data }) => this.videos = data,
|
||||
|
||||
complete: () => this.loaded.emit(true)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue