Add markdown support to video description
This commit is contained in:
parent
4077df72c6
commit
9d9597df42
10 changed files with 97 additions and 8 deletions
|
@ -35,6 +35,7 @@
|
|||
"@angularclass/hmr-loader": "^3.0.2",
|
||||
"@ngx-meta/core": "^4.0.1",
|
||||
"@types/core-js": "^0.9.28",
|
||||
"@types/markdown-it": "^0.0.4",
|
||||
"@types/node": "^8.0.33",
|
||||
"@types/source-map": "^0.5.1",
|
||||
"@types/uglify-js": "^2.0.27",
|
||||
|
@ -66,6 +67,7 @@
|
|||
"inline-manifest-webpack-plugin": "^3.0.1",
|
||||
"intl": "^1.2.4",
|
||||
"json-loader": "^0.5.4",
|
||||
"markdown-it": "^8.4.0",
|
||||
"ng-router-loader": "^2.0.0",
|
||||
"ngc-webpack": "3.2.2",
|
||||
"ngx-bootstrap": "1.9.3",
|
||||
|
|
|
@ -87,7 +87,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
|
|||
this.videoService.getVideo(uuid)
|
||||
.subscribe(
|
||||
video => {
|
||||
this.video = video
|
||||
this.video = new VideoEdit(video)
|
||||
|
||||
this.hydrateFormFromVideo()
|
||||
},
|
||||
|
|
|
@ -128,9 +128,7 @@
|
|||
Published on {{ video.createdAt | date:'short' }}
|
||||
</div>
|
||||
|
||||
<div class="video-details-description">
|
||||
{{ video.description }}
|
||||
</div>
|
||||
<div class="video-details-description" [innerHTML]="videoHTMLDescription"></div>
|
||||
</div>
|
||||
|
||||
<div class="video-details-attributes col-xs-4 col-md-3">
|
||||
|
|
|
@ -13,7 +13,7 @@ import { AuthService, ConfirmService } from '../../core'
|
|||
import { VideoDownloadComponent } from './video-download.component'
|
||||
import { VideoShareComponent } from './video-share.component'
|
||||
import { VideoReportComponent } from './video-report.component'
|
||||
import { VideoDetails, VideoService } from '../shared'
|
||||
import { VideoDetails, VideoService, MarkdownService } from '../shared'
|
||||
import { VideoBlacklistService } from '../../shared'
|
||||
import { UserVideoRateType, VideoRateType } from '../../../../../shared'
|
||||
|
||||
|
@ -38,6 +38,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
|||
video: VideoDetails = null
|
||||
videoPlayerLoaded = false
|
||||
videoNotFound = false
|
||||
videoHTMLDescription = ''
|
||||
|
||||
private paramsSub: Subscription
|
||||
|
||||
|
@ -50,7 +51,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
|||
private confirmService: ConfirmService,
|
||||
private metaService: MetaService,
|
||||
private authService: AuthService,
|
||||
private notificationsService: NotificationsService
|
||||
private notificationsService: NotificationsService,
|
||||
private markdownService: MarkdownService
|
||||
) {}
|
||||
|
||||
ngOnInit () {
|
||||
|
@ -259,6 +261,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
|||
})
|
||||
})
|
||||
|
||||
this.videoHTMLDescription = this.markdownService.markdownToHTML(this.video.description)
|
||||
|
||||
this.setOpenGraphTags()
|
||||
this.checkUserRating()
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { NgModule } from '@angular/core'
|
||||
|
||||
import { VideoWatchRoutingModule } from './video-watch-routing.module'
|
||||
import { VideoService } from '../shared'
|
||||
import { VideoService, MarkdownService } from '../shared'
|
||||
import { SharedModule } from '../../shared'
|
||||
|
||||
import { VideoWatchComponent } from './video-watch.component'
|
||||
|
@ -28,6 +28,7 @@ import { VideoDownloadComponent } from './video-download.component'
|
|||
],
|
||||
|
||||
providers: [
|
||||
MarkdownService,
|
||||
VideoService
|
||||
]
|
||||
})
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
export * from './sort-field.type'
|
||||
export * from './markdown.service'
|
||||
export * from './video.model'
|
||||
export * from './video-details.model'
|
||||
export * from './video-edit.model'
|
||||
|
|
40
client/src/app/videos/shared/markdown.service.ts
Normal file
40
client/src/app/videos/shared/markdown.service.ts
Normal file
|
@ -0,0 +1,40 @@
|
|||
import { Injectable } from '@angular/core'
|
||||
|
||||
import * as MarkdownIt from 'markdown-it'
|
||||
|
||||
@Injectable()
|
||||
export class MarkdownService {
|
||||
private markdownIt: MarkdownIt.MarkdownIt
|
||||
|
||||
constructor () {
|
||||
this.markdownIt = new MarkdownIt('zero', { linkify: true })
|
||||
.enable('linkify')
|
||||
.enable('autolink')
|
||||
.enable('emphasis')
|
||||
.enable('link')
|
||||
.enable('newline')
|
||||
|
||||
// Snippet from markdown-it documentation: https://github.com/markdown-it/markdown-it/blob/master/docs/architecture.md#renderer
|
||||
const defaultRender = this.markdownIt.renderer.rules.link_open || function (tokens, idx, options, env, self) {
|
||||
return self.renderToken(tokens, idx, options)
|
||||
}
|
||||
|
||||
this.markdownIt.renderer.rules.link_open = function (tokens, idx, options, env, self) {
|
||||
// If you are sure other plugins can't add `target` - drop check below
|
||||
const aIndex = tokens[idx].attrIndex('target')
|
||||
|
||||
if (aIndex < 0) {
|
||||
tokens[idx].attrPush(['target', '_blank']) // add new attribute
|
||||
} else {
|
||||
tokens[idx].attrs[aIndex][1] = '_blank' // replace value of existing attr
|
||||
}
|
||||
|
||||
// pass token to default renderer.
|
||||
return defaultRender(tokens, idx, options, env, self)
|
||||
}
|
||||
}
|
||||
|
||||
markdownToHTML (markdown: string) {
|
||||
return this.markdownIt.render(markdown)
|
||||
}
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
import { VideoDetails } from './video-details.model'
|
||||
|
||||
export class VideoEdit {
|
||||
category: number
|
||||
licence: number
|
||||
|
@ -10,6 +12,19 @@ export class VideoEdit {
|
|||
uuid?: string
|
||||
id?: number
|
||||
|
||||
constructor (videoDetails: VideoDetails) {
|
||||
this.id = videoDetails.id
|
||||
this.uuid = videoDetails.uuid
|
||||
this.category = videoDetails.category
|
||||
this.licence = videoDetails.licence
|
||||
this.language = videoDetails.language
|
||||
this.description = videoDetails.description
|
||||
this.name = videoDetails.name
|
||||
this.tags = videoDetails.tags
|
||||
this.nsfw = videoDetails.nsfw
|
||||
this.channel = videoDetails.channel.id
|
||||
}
|
||||
|
||||
patch (values: Object) {
|
||||
Object.keys(values).forEach((key) => {
|
||||
this[key] = values[key]
|
||||
|
|
|
@ -36,7 +36,7 @@ export class VideoService {
|
|||
private restService: RestService
|
||||
) {}
|
||||
|
||||
getVideo (uuid: string) {
|
||||
getVideo (uuid: string): Observable<VideoDetails> {
|
||||
return this.authHttp.get<VideoDetailsServerModel>(VideoService.BASE_VIDEO_URL + uuid)
|
||||
.map(videoHash => new VideoDetails(videoHash))
|
||||
.catch((res) => this.restExtractor.handleError(res))
|
||||
|
|
|
@ -102,6 +102,10 @@
|
|||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/markdown-it@^0.0.4":
|
||||
version "0.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-0.0.4.tgz#c5f67365916044b342dae8d702724788ba0b5b74"
|
||||
|
||||
"@types/node@*":
|
||||
version "8.0.25"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.25.tgz#66ecaf4df93f5281b48427ee96fbcdfc4f0cdce1"
|
||||
|
@ -3842,6 +3846,12 @@ levn@^0.3.0, levn@~0.3.0:
|
|||
prelude-ls "~1.1.2"
|
||||
type-check "~0.3.2"
|
||||
|
||||
linkify-it@^2.0.0:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.0.3.tgz#d94a4648f9b1c179d64fa97291268bdb6ce9434f"
|
||||
dependencies:
|
||||
uc.micro "^1.0.1"
|
||||
|
||||
load-ip-set@^1.2.7:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/load-ip-set/-/load-ip-set-1.3.1.tgz#cfd050c6916e7ba0ca85d0b566e7854713eb495e"
|
||||
|
@ -4169,6 +4179,16 @@ map-visit@^0.1.5:
|
|||
lazy-cache "^2.0.1"
|
||||
object-visit "^0.3.4"
|
||||
|
||||
markdown-it@^8.4.0:
|
||||
version "8.4.0"
|
||||
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.0.tgz#e2400881bf171f7018ed1bd9da441dac8af6306d"
|
||||
dependencies:
|
||||
argparse "^1.0.7"
|
||||
entities "~1.1.1"
|
||||
linkify-it "^2.0.0"
|
||||
mdurl "^1.0.1"
|
||||
uc.micro "^1.0.3"
|
||||
|
||||
marked-terminal@^1.6.2:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/marked-terminal/-/marked-terminal-1.7.0.tgz#c8c460881c772c7604b64367007ee5f77f125904"
|
||||
|
@ -4194,6 +4214,10 @@ md5.js@^1.3.4:
|
|||
hash-base "^3.0.0"
|
||||
inherits "^2.0.1"
|
||||
|
||||
mdurl@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
|
||||
|
||||
media-typer@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
|
@ -6824,6 +6848,10 @@ typescript@^2.5.2:
|
|||
version "2.5.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.5.3.tgz#df3dcdc38f3beb800d4bc322646b04a3f6ca7f0d"
|
||||
|
||||
uc.micro@^1.0.1, uc.micro@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.3.tgz#7ed50d5e0f9a9fb0a573379259f2a77458d50192"
|
||||
|
||||
uglify-js@3.0.x, uglify-js@^3.0.6:
|
||||
version "3.0.28"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.0.28.tgz#96b8495f0272944787b5843a1679aa326640d5f7"
|
||||
|
|
Loading…
Add table
Reference in a new issue