From 9d9597df427542eb5c7d3ba8ff5aeb146fab40e2 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 26 Oct 2017 15:01:47 +0200 Subject: Add markdown support to video description --- .../videos/+video-edit/video-update.component.ts | 2 +- .../videos/+video-watch/video-watch.component.html | 4 +-- .../videos/+video-watch/video-watch.component.ts | 8 +++-- .../app/videos/+video-watch/video-watch.module.ts | 3 +- client/src/app/videos/shared/index.ts | 1 + client/src/app/videos/shared/markdown.service.ts | 40 ++++++++++++++++++++++ client/src/app/videos/shared/video-edit.model.ts | 15 ++++++++ client/src/app/videos/shared/video.service.ts | 2 +- 8 files changed, 67 insertions(+), 8 deletions(-) create mode 100644 client/src/app/videos/shared/markdown.service.ts (limited to 'client/src') diff --git a/client/src/app/videos/+video-edit/video-update.component.ts b/client/src/app/videos/+video-edit/video-update.component.ts index 70cb334fd..30390ac05 100644 --- a/client/src/app/videos/+video-edit/video-update.component.ts +++ b/client/src/app/videos/+video-edit/video-update.component.ts @@ -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() }, diff --git a/client/src/app/videos/+video-watch/video-watch.component.html b/client/src/app/videos/+video-watch/video-watch.component.html index 5d5827344..6e502aae2 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.html +++ b/client/src/app/videos/+video-watch/video-watch.component.html @@ -128,9 +128,7 @@ Published on {{ video.createdAt | date:'short' }} -
- {{ video.description }} -
+
diff --git a/client/src/app/videos/+video-watch/video-watch.component.ts b/client/src/app/videos/+video-watch/video-watch.component.ts index 529e2e84f..2e1adb043 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.ts +++ b/client/src/app/videos/+video-watch/video-watch.component.ts @@ -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() } diff --git a/client/src/app/videos/+video-watch/video-watch.module.ts b/client/src/app/videos/+video-watch/video-watch.module.ts index c6c1344ce..1b983200d 100644 --- a/client/src/app/videos/+video-watch/video-watch.module.ts +++ b/client/src/app/videos/+video-watch/video-watch.module.ts @@ -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 ] }) diff --git a/client/src/app/videos/shared/index.ts b/client/src/app/videos/shared/index.ts index dcaa4e090..09d961dd3 100644 --- a/client/src/app/videos/shared/index.ts +++ b/client/src/app/videos/shared/index.ts @@ -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' diff --git a/client/src/app/videos/shared/markdown.service.ts b/client/src/app/videos/shared/markdown.service.ts new file mode 100644 index 000000000..d8b5b76b6 --- /dev/null +++ b/client/src/app/videos/shared/markdown.service.ts @@ -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) + } +} diff --git a/client/src/app/videos/shared/video-edit.model.ts b/client/src/app/videos/shared/video-edit.model.ts index f30d8feba..e0b7bf130 100644 --- a/client/src/app/videos/shared/video-edit.model.ts +++ b/client/src/app/videos/shared/video-edit.model.ts @@ -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] diff --git a/client/src/app/videos/shared/video.service.ts b/client/src/app/videos/shared/video.service.ts index 06fb3313e..8fdc1f213 100644 --- a/client/src/app/videos/shared/video.service.ts +++ b/client/src/app/videos/shared/video.service.ts @@ -36,7 +36,7 @@ export class VideoService { private restService: RestService ) {} - getVideo (uuid: string) { + getVideo (uuid: string): Observable { return this.authHttp.get(VideoService.BASE_VIDEO_URL + uuid) .map(videoHash => new VideoDetails(videoHash)) .catch((res) => this.restExtractor.handleError(res)) -- cgit v1.2.3