diff --git a/client/src/app/shared/shared-custom-markup/button-markup.component.html b/client/src/app/shared/shared-custom-markup/button-markup.component.html
new file mode 100644
index 000000000..619bb9d8c
--- /dev/null
+++ b/client/src/app/shared/shared-custom-markup/button-markup.component.html
@@ -0,0 +1 @@
+{{ label }}
diff --git a/client/src/app/shared/shared-custom-markup/button-markup.component.scss b/client/src/app/shared/shared-custom-markup/button-markup.component.scss
new file mode 100644
index 000000000..f43d6b400
--- /dev/null
+++ b/client/src/app/shared/shared-custom-markup/button-markup.component.scss
@@ -0,0 +1,3 @@
+@import '_variables';
+@import '_mixins';
+
diff --git a/client/src/app/shared/shared-custom-markup/button-markup.component.ts b/client/src/app/shared/shared-custom-markup/button-markup.component.ts
new file mode 100644
index 000000000..c0aab2edd
--- /dev/null
+++ b/client/src/app/shared/shared-custom-markup/button-markup.component.ts
@@ -0,0 +1,34 @@
+import { Component, Input } from '@angular/core'
+import { VideoChannel } from '../shared-main'
+
+/*
+ * Markup component that creates a button
+*/
+
+@Component({
+ selector: 'my-button-markup',
+ templateUrl: 'button-markup.component.html',
+ styleUrls: [ 'button-markup.component.scss' ]
+})
+export class ButtonMarkupComponent {
+ @Input() theme: 'primary' | 'secondary'
+ @Input() href: string
+ @Input() label: string
+ @Input() blankTarget?: boolean
+
+ channel: VideoChannel
+
+ getTarget () {
+ if (this.blankTarget === true) return '_blank'
+
+ return ''
+ }
+
+ getClasses () {
+ const additionalClass = this.theme === 'primary'
+ ? 'orange-button'
+ : 'grey-button'
+
+ return [ 'peertube-button-link', additionalClass ]
+ }
+}
diff --git a/client/src/app/shared/shared-custom-markup/custom-markup.service.ts b/client/src/app/shared/shared-custom-markup/custom-markup.service.ts
index ffaf15710..09414da95 100644
--- a/client/src/app/shared/shared-custom-markup/custom-markup.service.ts
+++ b/client/src/app/shared/shared-custom-markup/custom-markup.service.ts
@@ -1,12 +1,14 @@
import { ComponentRef, Injectable } from '@angular/core'
import { MarkdownService } from '@app/core'
import {
+ ButtonMarkupData,
ChannelMiniatureMarkupData,
EmbedMarkupData,
PlaylistMiniatureMarkupData,
VideoMiniatureMarkupData,
VideosListMarkupData
} from '@shared/models'
+import { ButtonMarkupComponent } from './button-markup.component'
import { ChannelMiniatureMarkupComponent } from './channel-miniature-markup.component'
import { DynamicElementService } from './dynamic-element.service'
import { EmbedMarkupComponent } from './embed-markup.component'
@@ -19,6 +21,7 @@ type BuilderFunction = (el: HTMLElement) => ComponentRef
@Injectable()
export class CustomMarkupService {
private builders: { [ selector: string ]: BuilderFunction } = {
+ 'peertube-button': el => this.buttonBuilder(el),
'peertube-video-embed': el => this.embedBuilder(el, 'video'),
'peertube-playlist-embed': el => this.embedBuilder(el, 'playlist'),
'peertube-video-miniature': el => this.videoMiniatureBuilder(el),
@@ -98,6 +101,21 @@ export class CustomMarkupService {
return component
}
+ private buttonBuilder (el: HTMLElement) {
+ const data = el.dataset as ButtonMarkupData
+ const component = this.dynamicElementService.createElement(ButtonMarkupComponent)
+
+ const model = {
+ theme: data.theme,
+ href: data.href,
+ label: data.label,
+ blankTarget: this.buildBoolean(data.blankTarget)
+ }
+ this.dynamicElementService.setModel(component, model)
+
+ return component
+ }
+
private videosListBuilder (el: HTMLElement) {
const data = el.dataset as VideosListMarkupData
const component = this.dynamicElementService.createElement(VideosListMarkupComponent)
@@ -122,6 +140,13 @@ export class CustomMarkupService {
return parseInt(value, 10)
}
+ private buildBoolean (value: string) {
+ if (value === 'true') return true
+ if (value === 'false') return false
+
+ return undefined
+ }
+
private buildArrayNumber (value: string) {
if (!value) return undefined
diff --git a/client/src/app/shared/shared-custom-markup/shared-custom-markup.module.ts b/client/src/app/shared/shared-custom-markup/shared-custom-markup.module.ts
index 4bbb71588..d03aa856f 100644
--- a/client/src/app/shared/shared-custom-markup/shared-custom-markup.module.ts
+++ b/client/src/app/shared/shared-custom-markup/shared-custom-markup.module.ts
@@ -6,6 +6,7 @@ import { SharedGlobalIconModule } from '../shared-icons'
import { SharedMainModule } from '../shared-main'
import { SharedVideoMiniatureModule } from '../shared-video-miniature'
import { SharedVideoPlaylistModule } from '../shared-video-playlist'
+import { ButtonMarkupComponent } from './button-markup.component'
import { ChannelMiniatureMarkupComponent } from './channel-miniature-markup.component'
import { CustomMarkupService } from './custom-markup.service'
import { DynamicElementService } from './dynamic-element.service'
@@ -30,7 +31,8 @@ import { VideosListMarkupComponent } from './videos-list-markup.component'
PlaylistMiniatureMarkupComponent,
ChannelMiniatureMarkupComponent,
EmbedMarkupComponent,
- VideosListMarkupComponent
+ VideosListMarkupComponent,
+ ButtonMarkupComponent
],
exports: [
@@ -38,7 +40,8 @@ import { VideosListMarkupComponent } from './videos-list-markup.component'
PlaylistMiniatureMarkupComponent,
ChannelMiniatureMarkupComponent,
VideosListMarkupComponent,
- EmbedMarkupComponent
+ EmbedMarkupComponent,
+ ButtonMarkupComponent
],
providers: [
diff --git a/shared/models/custom-markup/custom-markup-data.model.ts b/shared/models/custom-markup/custom-markup-data.model.ts
index af697428e..24ac3706c 100644
--- a/shared/models/custom-markup/custom-markup-data.model.ts
+++ b/shared/models/custom-markup/custom-markup-data.model.ts
@@ -26,3 +26,10 @@ export type VideosListMarkupData = {
languageOneOf: string // coma separated values
count: string
}
+
+export type ButtonMarkupData = {
+ theme: 'primary' | 'secondary'
+ href: string
+ label: string
+ blankTarget?: string
+}