aboutsummaryrefslogtreecommitdiffhomepage
path: root/client
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2017-10-26 15:01:47 +0200
committerChocobozzz <florian.bigard@gmail.com>2017-10-26 15:01:47 +0200
commit9d9597df427542eb5c7d3ba8ff5aeb146fab40e2 (patch)
tree5098facc5f2d70d4ad7871e6736e6f9d9d9a797a /client
parent4077df72c634ff17aaf69cc612fc6bb8d68b1ed8 (diff)
downloadPeerTube-9d9597df427542eb5c7d3ba8ff5aeb146fab40e2.tar.gz
PeerTube-9d9597df427542eb5c7d3ba8ff5aeb146fab40e2.tar.zst
PeerTube-9d9597df427542eb5c7d3ba8ff5aeb146fab40e2.zip
Add markdown support to video description
Diffstat (limited to 'client')
-rw-r--r--client/package.json2
-rw-r--r--client/src/app/videos/+video-edit/video-update.component.ts2
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.html4
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.ts8
-rw-r--r--client/src/app/videos/+video-watch/video-watch.module.ts3
-rw-r--r--client/src/app/videos/shared/index.ts1
-rw-r--r--client/src/app/videos/shared/markdown.service.ts40
-rw-r--r--client/src/app/videos/shared/video-edit.model.ts15
-rw-r--r--client/src/app/videos/shared/video.service.ts2
-rw-r--r--client/yarn.lock28
10 files changed, 97 insertions, 8 deletions
diff --git a/client/package.json b/client/package.json
index 8b949ef80..8d42e0c87 100644
--- a/client/package.json
+++ b/client/package.json
@@ -35,6 +35,7 @@
35 "@angularclass/hmr-loader": "^3.0.2", 35 "@angularclass/hmr-loader": "^3.0.2",
36 "@ngx-meta/core": "^4.0.1", 36 "@ngx-meta/core": "^4.0.1",
37 "@types/core-js": "^0.9.28", 37 "@types/core-js": "^0.9.28",
38 "@types/markdown-it": "^0.0.4",
38 "@types/node": "^8.0.33", 39 "@types/node": "^8.0.33",
39 "@types/source-map": "^0.5.1", 40 "@types/source-map": "^0.5.1",
40 "@types/uglify-js": "^2.0.27", 41 "@types/uglify-js": "^2.0.27",
@@ -66,6 +67,7 @@
66 "inline-manifest-webpack-plugin": "^3.0.1", 67 "inline-manifest-webpack-plugin": "^3.0.1",
67 "intl": "^1.2.4", 68 "intl": "^1.2.4",
68 "json-loader": "^0.5.4", 69 "json-loader": "^0.5.4",
70 "markdown-it": "^8.4.0",
69 "ng-router-loader": "^2.0.0", 71 "ng-router-loader": "^2.0.0",
70 "ngc-webpack": "3.2.2", 72 "ngc-webpack": "3.2.2",
71 "ngx-bootstrap": "1.9.3", 73 "ngx-bootstrap": "1.9.3",
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 {
87 this.videoService.getVideo(uuid) 87 this.videoService.getVideo(uuid)
88 .subscribe( 88 .subscribe(
89 video => { 89 video => {
90 this.video = video 90 this.video = new VideoEdit(video)
91 91
92 this.hydrateFormFromVideo() 92 this.hydrateFormFromVideo()
93 }, 93 },
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 @@
128 Published on {{ video.createdAt | date:'short' }} 128 Published on {{ video.createdAt | date:'short' }}
129 </div> 129 </div>
130 130
131 <div class="video-details-description"> 131 <div class="video-details-description" [innerHTML]="videoHTMLDescription"></div>
132 {{ video.description }}
133 </div>
134 </div> 132 </div>
135 133
136 <div class="video-details-attributes col-xs-4 col-md-3"> 134 <div class="video-details-attributes col-xs-4 col-md-3">
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'
13import { VideoDownloadComponent } from './video-download.component' 13import { VideoDownloadComponent } from './video-download.component'
14import { VideoShareComponent } from './video-share.component' 14import { VideoShareComponent } from './video-share.component'
15import { VideoReportComponent } from './video-report.component' 15import { VideoReportComponent } from './video-report.component'
16import { VideoDetails, VideoService } from '../shared' 16import { VideoDetails, VideoService, MarkdownService } from '../shared'
17import { VideoBlacklistService } from '../../shared' 17import { VideoBlacklistService } from '../../shared'
18import { UserVideoRateType, VideoRateType } from '../../../../../shared' 18import { UserVideoRateType, VideoRateType } from '../../../../../shared'
19 19
@@ -38,6 +38,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
38 video: VideoDetails = null 38 video: VideoDetails = null
39 videoPlayerLoaded = false 39 videoPlayerLoaded = false
40 videoNotFound = false 40 videoNotFound = false
41 videoHTMLDescription = ''
41 42
42 private paramsSub: Subscription 43 private paramsSub: Subscription
43 44
@@ -50,7 +51,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
50 private confirmService: ConfirmService, 51 private confirmService: ConfirmService,
51 private metaService: MetaService, 52 private metaService: MetaService,
52 private authService: AuthService, 53 private authService: AuthService,
53 private notificationsService: NotificationsService 54 private notificationsService: NotificationsService,
55 private markdownService: MarkdownService
54 ) {} 56 ) {}
55 57
56 ngOnInit () { 58 ngOnInit () {
@@ -259,6 +261,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
259 }) 261 })
260 }) 262 })
261 263
264 this.videoHTMLDescription = this.markdownService.markdownToHTML(this.video.description)
265
262 this.setOpenGraphTags() 266 this.setOpenGraphTags()
263 this.checkUserRating() 267 this.checkUserRating()
264 } 268 }
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 @@
1import { NgModule } from '@angular/core' 1import { NgModule } from '@angular/core'
2 2
3import { VideoWatchRoutingModule } from './video-watch-routing.module' 3import { VideoWatchRoutingModule } from './video-watch-routing.module'
4import { VideoService } from '../shared' 4import { VideoService, MarkdownService } from '../shared'
5import { SharedModule } from '../../shared' 5import { SharedModule } from '../../shared'
6 6
7import { VideoWatchComponent } from './video-watch.component' 7import { VideoWatchComponent } from './video-watch.component'
@@ -28,6 +28,7 @@ import { VideoDownloadComponent } from './video-download.component'
28 ], 28 ],
29 29
30 providers: [ 30 providers: [
31 MarkdownService,
31 VideoService 32 VideoService
32 ] 33 ]
33}) 34})
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 @@
1export * from './sort-field.type' 1export * from './sort-field.type'
2export * from './markdown.service'
2export * from './video.model' 3export * from './video.model'
3export * from './video-details.model' 4export * from './video-details.model'
4export * from './video-edit.model' 5export * 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 @@
1import { Injectable } from '@angular/core'
2
3import * as MarkdownIt from 'markdown-it'
4
5@Injectable()
6export class MarkdownService {
7 private markdownIt: MarkdownIt.MarkdownIt
8
9 constructor () {
10 this.markdownIt = new MarkdownIt('zero', { linkify: true })
11 .enable('linkify')
12 .enable('autolink')
13 .enable('emphasis')
14 .enable('link')
15 .enable('newline')
16
17 // Snippet from markdown-it documentation: https://github.com/markdown-it/markdown-it/blob/master/docs/architecture.md#renderer
18 const defaultRender = this.markdownIt.renderer.rules.link_open || function (tokens, idx, options, env, self) {
19 return self.renderToken(tokens, idx, options)
20 }
21
22 this.markdownIt.renderer.rules.link_open = function (tokens, idx, options, env, self) {
23 // If you are sure other plugins can't add `target` - drop check below
24 const aIndex = tokens[idx].attrIndex('target')
25
26 if (aIndex < 0) {
27 tokens[idx].attrPush(['target', '_blank']) // add new attribute
28 } else {
29 tokens[idx].attrs[aIndex][1] = '_blank' // replace value of existing attr
30 }
31
32 // pass token to default renderer.
33 return defaultRender(tokens, idx, options, env, self)
34 }
35 }
36
37 markdownToHTML (markdown: string) {
38 return this.markdownIt.render(markdown)
39 }
40}
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 @@
1import { VideoDetails } from './video-details.model'
2
1export class VideoEdit { 3export class VideoEdit {
2 category: number 4 category: number
3 licence: number 5 licence: number
@@ -10,6 +12,19 @@ export class VideoEdit {
10 uuid?: string 12 uuid?: string
11 id?: number 13 id?: number
12 14
15 constructor (videoDetails: VideoDetails) {
16 this.id = videoDetails.id
17 this.uuid = videoDetails.uuid
18 this.category = videoDetails.category
19 this.licence = videoDetails.licence
20 this.language = videoDetails.language
21 this.description = videoDetails.description
22 this.name = videoDetails.name
23 this.tags = videoDetails.tags
24 this.nsfw = videoDetails.nsfw
25 this.channel = videoDetails.channel.id
26 }
27
13 patch (values: Object) { 28 patch (values: Object) {
14 Object.keys(values).forEach((key) => { 29 Object.keys(values).forEach((key) => {
15 this[key] = values[key] 30 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 {
36 private restService: RestService 36 private restService: RestService
37 ) {} 37 ) {}
38 38
39 getVideo (uuid: string) { 39 getVideo (uuid: string): Observable<VideoDetails> {
40 return this.authHttp.get<VideoDetailsServerModel>(VideoService.BASE_VIDEO_URL + uuid) 40 return this.authHttp.get<VideoDetailsServerModel>(VideoService.BASE_VIDEO_URL + uuid)
41 .map(videoHash => new VideoDetails(videoHash)) 41 .map(videoHash => new VideoDetails(videoHash))
42 .catch((res) => this.restExtractor.handleError(res)) 42 .catch((res) => this.restExtractor.handleError(res))
diff --git a/client/yarn.lock b/client/yarn.lock
index b63c76e2f..23ab3a3df 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -102,6 +102,10 @@
102 dependencies: 102 dependencies:
103 "@types/node" "*" 103 "@types/node" "*"
104 104
105"@types/markdown-it@^0.0.4":
106 version "0.0.4"
107 resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-0.0.4.tgz#c5f67365916044b342dae8d702724788ba0b5b74"
108
105"@types/node@*": 109"@types/node@*":
106 version "8.0.25" 110 version "8.0.25"
107 resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.25.tgz#66ecaf4df93f5281b48427ee96fbcdfc4f0cdce1" 111 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:
3842 prelude-ls "~1.1.2" 3846 prelude-ls "~1.1.2"
3843 type-check "~0.3.2" 3847 type-check "~0.3.2"
3844 3848
3849linkify-it@^2.0.0:
3850 version "2.0.3"
3851 resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.0.3.tgz#d94a4648f9b1c179d64fa97291268bdb6ce9434f"
3852 dependencies:
3853 uc.micro "^1.0.1"
3854
3845load-ip-set@^1.2.7: 3855load-ip-set@^1.2.7:
3846 version "1.3.1" 3856 version "1.3.1"
3847 resolved "https://registry.yarnpkg.com/load-ip-set/-/load-ip-set-1.3.1.tgz#cfd050c6916e7ba0ca85d0b566e7854713eb495e" 3857 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:
4169 lazy-cache "^2.0.1" 4179 lazy-cache "^2.0.1"
4170 object-visit "^0.3.4" 4180 object-visit "^0.3.4"
4171 4181
4182markdown-it@^8.4.0:
4183 version "8.4.0"
4184 resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.0.tgz#e2400881bf171f7018ed1bd9da441dac8af6306d"
4185 dependencies:
4186 argparse "^1.0.7"
4187 entities "~1.1.1"
4188 linkify-it "^2.0.0"
4189 mdurl "^1.0.1"
4190 uc.micro "^1.0.3"
4191
4172marked-terminal@^1.6.2: 4192marked-terminal@^1.6.2:
4173 version "1.7.0" 4193 version "1.7.0"
4174 resolved "https://registry.yarnpkg.com/marked-terminal/-/marked-terminal-1.7.0.tgz#c8c460881c772c7604b64367007ee5f77f125904" 4194 resolved "https://registry.yarnpkg.com/marked-terminal/-/marked-terminal-1.7.0.tgz#c8c460881c772c7604b64367007ee5f77f125904"
@@ -4194,6 +4214,10 @@ md5.js@^1.3.4:
4194 hash-base "^3.0.0" 4214 hash-base "^3.0.0"
4195 inherits "^2.0.1" 4215 inherits "^2.0.1"
4196 4216
4217mdurl@^1.0.1:
4218 version "1.0.1"
4219 resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
4220
4197media-typer@0.3.0: 4221media-typer@0.3.0:
4198 version "0.3.0" 4222 version "0.3.0"
4199 resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 4223 resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
@@ -6824,6 +6848,10 @@ typescript@^2.5.2:
6824 version "2.5.3" 6848 version "2.5.3"
6825 resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.5.3.tgz#df3dcdc38f3beb800d4bc322646b04a3f6ca7f0d" 6849 resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.5.3.tgz#df3dcdc38f3beb800d4bc322646b04a3f6ca7f0d"
6826 6850
6851uc.micro@^1.0.1, uc.micro@^1.0.3:
6852 version "1.0.3"
6853 resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.3.tgz#7ed50d5e0f9a9fb0a573379259f2a77458d50192"
6854
6827uglify-js@3.0.x, uglify-js@^3.0.6: 6855uglify-js@3.0.x, uglify-js@^3.0.6:
6828 version "3.0.28" 6856 version "3.0.28"
6829 resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.0.28.tgz#96b8495f0272944787b5843a1679aa326640d5f7" 6857 resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.0.28.tgz#96b8495f0272944787b5843a1679aa326640d5f7"