diff options
author | Lesterpig <git@lesterpig.com> | 2019-10-02 21:17:10 +0200 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2019-12-17 09:45:02 +0100 |
commit | d68ebf0b4a40f88e53a78de6b3109a41466fa7c6 (patch) | |
tree | bbe02b16b88351b354c99f959c888d36444e719c /client/src/app/shared | |
parent | a0dedc02ca870a31298eb35d5105a1ebc34dbb4a (diff) | |
download | PeerTube-d68ebf0b4a40f88e53a78de6b3109a41466fa7c6.tar.gz PeerTube-d68ebf0b4a40f88e53a78de6b3109a41466fa7c6.tar.zst PeerTube-d68ebf0b4a40f88e53a78de6b3109a41466fa7c6.zip |
Add hyperlink video timestamps in description
Fix #1312 (duplicates: #1728 and #2007)
The modification is also applied to comments and video editing.
Diffstat (limited to 'client/src/app/shared')
-rw-r--r-- | client/src/app/shared/forms/markdown-textarea.component.ts | 9 | ||||
-rw-r--r-- | client/src/app/shared/renderer/markdown.service.ts | 11 |
2 files changed, 16 insertions, 4 deletions
diff --git a/client/src/app/shared/forms/markdown-textarea.component.ts b/client/src/app/shared/forms/markdown-textarea.component.ts index 49a57f29d..0c5788899 100644 --- a/client/src/app/shared/forms/markdown-textarea.component.ts +++ b/client/src/app/shared/forms/markdown-textarea.component.ts | |||
@@ -27,6 +27,7 @@ export class MarkdownTextareaComponent implements ControlValueAccessor, OnInit { | |||
27 | @Input() previewColumn = false | 27 | @Input() previewColumn = false |
28 | @Input() truncate: number | 28 | @Input() truncate: number |
29 | @Input() markdownType: 'text' | 'enhanced' = 'text' | 29 | @Input() markdownType: 'text' | 'enhanced' = 'text' |
30 | @Input() markdownVideo = false | ||
30 | 31 | ||
31 | textareaMarginRight = '0' | 32 | textareaMarginRight = '0' |
32 | flexDirection = 'column' | 33 | flexDirection = 'column' |
@@ -89,9 +90,11 @@ export class MarkdownTextareaComponent implements ControlValueAccessor, OnInit { | |||
89 | this.previewHTML = await this.markdownRender(this.content) | 90 | this.previewHTML = await this.markdownRender(this.content) |
90 | } | 91 | } |
91 | 92 | ||
92 | private markdownRender (text: string) { | 93 | private async markdownRender (text: string) { |
93 | if (this.markdownType === 'text') return this.markdownService.textMarkdownToHTML(text) | 94 | const html = this.markdownType === 'text' ? |
95 | await this.markdownService.textMarkdownToHTML(text) : | ||
96 | await this.markdownService.enhancedMarkdownToHTML(text) | ||
94 | 97 | ||
95 | return this.markdownService.enhancedMarkdownToHTML(text) | 98 | return this.markdownVideo ? this.markdownService.processVideoTimestamps(html) : html |
96 | } | 99 | } |
97 | } | 100 | } |
diff --git a/client/src/app/shared/renderer/markdown.service.ts b/client/src/app/shared/renderer/markdown.service.ts index 629bbb140..f6b71b88a 100644 --- a/client/src/app/shared/renderer/markdown.service.ts +++ b/client/src/app/shared/renderer/markdown.service.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | import { Injectable } from '@angular/core' | 1 | import { Injectable } from '@angular/core' |
2 | import { MarkdownIt } from 'markdown-it' | 2 | import { MarkdownIt } from 'markdown-it' |
3 | import { buildVideoLink } from '../../../assets/player/utils' | ||
3 | import { HtmlRendererService } from '@app/shared/renderer/html-renderer.service' | 4 | import { HtmlRendererService } from '@app/shared/renderer/html-renderer.service' |
4 | 5 | ||
5 | type MarkdownParsers = { | 6 | type MarkdownParsers = { |
@@ -90,6 +91,14 @@ export class MarkdownService { | |||
90 | return html | 91 | return html |
91 | } | 92 | } |
92 | 93 | ||
94 | async processVideoTimestamps (html: string) { | ||
95 | return html.replace(/((\d{1,2}):)?(\d{1,2}):(\d{1,2})/g, function (str, _, h, m, s) { | ||
96 | const t = (3600 * +(h || 0)) + (60 * +(m || 0)) + (+(s || 0)) | ||
97 | const url = buildVideoLink({ startTime: t }) | ||
98 | return `<a href="${url}">${str}</a>` | ||
99 | }) | ||
100 | } | ||
101 | |||
93 | private async createMarkdownIt (config: MarkdownConfig) { | 102 | private async createMarkdownIt (config: MarkdownConfig) { |
94 | // FIXME: import('...') returns a struct module, containing a "default" field corresponding to our sanitizeHtml function | 103 | // FIXME: import('...') returns a struct module, containing a "default" field corresponding to our sanitizeHtml function |
95 | const MarkdownItClass: typeof import ('markdown-it') = (await import('markdown-it') as any).default | 104 | const MarkdownItClass: typeof import ('markdown-it') = (await import('markdown-it') as any).default |
@@ -130,7 +139,7 @@ export class MarkdownService { | |||
130 | private avoidTruncatedTags (html: string) { | 139 | private avoidTruncatedTags (html: string) { |
131 | return html.replace(/\*\*?([^*]+)$/, '$1') | 140 | return html.replace(/\*\*?([^*]+)$/, '$1') |
132 | .replace(/<a[^>]+>([^<]+)<\/a>\s*...((<\/p>)|(<\/li>)|(<\/strong>))?$/mi, '$1...') | 141 | .replace(/<a[^>]+>([^<]+)<\/a>\s*...((<\/p>)|(<\/li>)|(<\/strong>))?$/mi, '$1...') |
133 | .replace(/\[[^\]]+\]\(([^\)]+)$/m, '$1') | 142 | .replace(/\[[^\]]+\]?\(?([^\)]+)$/, '$1') |
134 | .replace(/\s?\[[^\]]+\]?[.]{3}<\/p>$/m, '...</p>') | 143 | .replace(/\s?\[[^\]]+\]?[.]{3}<\/p>$/m, '...</p>') |
135 | } | 144 | } |
136 | } | 145 | } |