Create peertube-container html tag
This commit is contained in:
parent
17b064e394
commit
f7894f0964
|
@ -1 +1 @@
|
|||
<div #contentWrapper></div>
|
||||
<div class="custom-markup-container" #contentWrapper></div>
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
.custom-markup-container {
|
||||
|
||||
::ng-deep .peertube-container {
|
||||
margin: 30px 0 15px;
|
||||
|
||||
h4 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,8 @@ import { CustomMarkupService } from './custom-markup.service'
|
|||
|
||||
@Component({
|
||||
selector: 'my-custom-markup-container',
|
||||
templateUrl: './custom-markup-container.component.html'
|
||||
templateUrl: './custom-markup-container.component.html',
|
||||
styleUrls: [ './custom-markup-container.component.scss' ]
|
||||
})
|
||||
export class CustomMarkupContainerComponent implements OnChanges {
|
||||
@ViewChild('contentWrapper') contentWrapper: ElementRef<HTMLInputElement>
|
||||
|
|
|
@ -3,6 +3,7 @@ import { MarkdownService } from '@app/core'
|
|||
import {
|
||||
ButtonMarkupData,
|
||||
ChannelMiniatureMarkupData,
|
||||
ContainerMarkupData,
|
||||
EmbedMarkupData,
|
||||
PlaylistMiniatureMarkupData,
|
||||
VideoMiniatureMarkupData,
|
||||
|
@ -18,11 +19,12 @@ import {
|
|||
VideosListMarkupComponent
|
||||
} from './peertube-custom-tags'
|
||||
|
||||
type BuilderFunction = (el: HTMLElement) => ComponentRef<any>
|
||||
type AngularBuilderFunction = (el: HTMLElement) => ComponentRef<any>
|
||||
type HTMLBuilderFunction = (el: HTMLElement) => HTMLElement
|
||||
|
||||
@Injectable()
|
||||
export class CustomMarkupService {
|
||||
private builders: { [ selector: string ]: BuilderFunction } = {
|
||||
private angularBuilders: { [ selector: string ]: AngularBuilderFunction } = {
|
||||
'peertube-button': el => this.buttonBuilder(el),
|
||||
'peertube-video-embed': el => this.embedBuilder(el, 'video'),
|
||||
'peertube-playlist-embed': el => this.embedBuilder(el, 'playlist'),
|
||||
|
@ -32,6 +34,10 @@ export class CustomMarkupService {
|
|||
'peertube-videos-list': el => this.videosListBuilder(el)
|
||||
}
|
||||
|
||||
private htmlBuilders: { [ selector: string ]: HTMLBuilderFunction } = {
|
||||
'peertube-container': el => this.containerBuilder(el)
|
||||
}
|
||||
|
||||
private customMarkdownRenderer: (text: string) => Promise<HTMLElement>
|
||||
|
||||
constructor (
|
||||
|
@ -51,11 +57,24 @@ export class CustomMarkupService {
|
|||
const rootElement = document.createElement('div')
|
||||
rootElement.innerHTML = html
|
||||
|
||||
for (const selector of this.getSupportedTags()) {
|
||||
for (const selector of Object.keys(this.htmlBuilders)) {
|
||||
rootElement.querySelectorAll(selector)
|
||||
.forEach((e: HTMLElement) => {
|
||||
try {
|
||||
const component = this.execBuilder(selector, e)
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
for (const selector of Object.keys(this.angularBuilders)) {
|
||||
rootElement.querySelectorAll(selector)
|
||||
.forEach((e: HTMLElement) => {
|
||||
try {
|
||||
const component = this.execAngularBuilder(selector, e)
|
||||
|
||||
this.dynamicElementService.injectElement(e, component)
|
||||
} catch (err) {
|
||||
|
@ -68,11 +87,16 @@ export class CustomMarkupService {
|
|||
}
|
||||
|
||||
private getSupportedTags () {
|
||||
return Object.keys(this.builders)
|
||||
return Object.keys(this.angularBuilders)
|
||||
.concat(Object.keys(this.htmlBuilders))
|
||||
}
|
||||
|
||||
private execBuilder (selector: string, el: HTMLElement) {
|
||||
return this.builders[selector](el)
|
||||
private execHTMLBuilder (selector: string, el: HTMLElement) {
|
||||
return this.htmlBuilders[selector](el)
|
||||
}
|
||||
|
||||
private execAngularBuilder (selector: string, el: HTMLElement) {
|
||||
return this.angularBuilders[selector](el)
|
||||
}
|
||||
|
||||
private embedBuilder (el: HTMLElement, type: 'video' | 'playlist') {
|
||||
|
@ -131,8 +155,6 @@ export class CustomMarkupService {
|
|||
const component = this.dynamicElementService.createElement(VideosListMarkupComponent)
|
||||
|
||||
const model = {
|
||||
title: data.title,
|
||||
description: data.description,
|
||||
sort: data.sort,
|
||||
categoryOneOf: this.buildArrayNumber(data.categoryOneOf),
|
||||
languageOneOf: this.buildArrayString(data.languageOneOf),
|
||||
|
@ -144,6 +166,31 @@ export class CustomMarkupService {
|
|||
return component
|
||||
}
|
||||
|
||||
private containerBuilder (el: HTMLElement) {
|
||||
const data = el.dataset as ContainerMarkupData
|
||||
|
||||
const root = document.createElement('div')
|
||||
root.classList.add('peertube-container')
|
||||
|
||||
if (data.width) {
|
||||
root.setAttribute('width', data.width)
|
||||
}
|
||||
|
||||
if (data.title) {
|
||||
const titleElement = document.createElement('h4')
|
||||
titleElement.innerText = data.title
|
||||
root.appendChild(titleElement)
|
||||
}
|
||||
|
||||
if (data.description) {
|
||||
const descriptionElement = document.createElement('div')
|
||||
descriptionElement.innerText = data.description
|
||||
root.appendChild(descriptionElement)
|
||||
}
|
||||
|
||||
return root
|
||||
}
|
||||
|
||||
private buildNumber (value: string) {
|
||||
if (!value) return undefined
|
||||
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
<div class="root">
|
||||
<h4 *ngIf="title">{{ title }}</h4>
|
||||
<div *ngIf="description" class="description">{{ description }}</div>
|
||||
|
||||
<div class="videos">
|
||||
<my-video-miniature
|
||||
*ngFor="let video of videos"
|
||||
[video]="video" [user]="getUser()" [displayAsRow]="false"
|
||||
[displayVideoActions]="false" [displayOptions]="displayOptions"
|
||||
>
|
||||
</my-video-miniature>
|
||||
</div>
|
||||
<div class="videos">
|
||||
<my-video-miniature
|
||||
*ngFor="let video of videos"
|
||||
[video]="video" [user]="getUser()" [displayAsRow]="false"
|
||||
[displayVideoActions]="false" [displayOptions]="displayOptions"
|
||||
>
|
||||
</my-video-miniature>
|
||||
</div>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
my-video-miniature {
|
||||
@include margin-right(15px);
|
||||
|
||||
display: inline-block;
|
||||
min-width: $video-thumbnail-width;
|
||||
max-width: $video-thumbnail-width;
|
||||
|
|
|
@ -14,8 +14,6 @@ import { MiniatureDisplayOptions } from '../../shared-video-miniature'
|
|||
styleUrls: [ 'videos-list-markup.component.scss' ]
|
||||
})
|
||||
export class VideosListMarkupComponent implements OnInit {
|
||||
@Input() title: string
|
||||
@Input() description: string
|
||||
@Input() sort = '-publishedAt'
|
||||
@Input() categoryOneOf: number[]
|
||||
@Input() languageOneOf: string[]
|
||||
|
|
|
@ -19,8 +19,6 @@ export type ChannelMiniatureMarkupData = {
|
|||
}
|
||||
|
||||
export type VideosListMarkupData = {
|
||||
title: string
|
||||
description: string
|
||||
sort: string
|
||||
categoryOneOf: string // coma separated values
|
||||
languageOneOf: string // coma separated values
|
||||
|
@ -33,3 +31,9 @@ export type ButtonMarkupData = {
|
|||
label: string
|
||||
blankTarget?: string
|
||||
}
|
||||
|
||||
export type ContainerMarkupData = {
|
||||
width?: string
|
||||
title?: string
|
||||
description?: string
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue