diff --git a/client/src/components/chat.vue b/client/src/components/chat.vue index c8e127de..28ae988e 100644 --- a/client/src/components/chat.vue +++ b/client/src/components/chat.vue @@ -18,7 +18,11 @@ {{ member(message.id).displayname }} {{ timestamp(message.created) }} - +
  • @@ -225,6 +229,11 @@ display: block; } } + + .open-in-app { + margin-left: 0.3em; + cursor: pointer; + } } } @@ -460,6 +469,27 @@ target.parentElement.classList.add('active') event.preventDefault() } + + if (target.classList.contains('open-in-app')) { + const href = target.dataset.href + if (href) { + this.$accessor.openinapp.sendOpenLink(href) + } + event.preventDefault() + } + + if ( + this.$accessor.settings.links_in_app && + this.$accessor.openinapp.enabled && + this.$accessor.remote.hosting && + target.tagName.toLowerCase() === 'a' + ) { + const href = target.getAttribute('href') + if (href) { + this.$accessor.openinapp.sendOpenLink(href) + event.preventDefault() + } + } } onKeyDown(event: KeyboardEvent) { diff --git a/client/src/components/markdown.ts b/client/src/components/markdown.ts index 38c6c357..f0b62c6e 100644 --- a/client/src/components/markdown.ts +++ b/client/src/components/markdown.ts @@ -136,12 +136,21 @@ const rules: MarkdownRules = { } }, html(node, output, state) { - return htmlTag( + const href = md.sanitizeUrl(node.target) as string + const link = htmlTag( 'a', output(node.content, state), { href: md.sanitizeUrl(node.target) as string, target: '_blank' }, state, ) + if (!state.openInApp) return link + const inAppIcon = htmlTag( + 'i', + '', + { class: 'open-in-app fas fa-arrow-up-right-from-square', 'data-href': href }, + state, + ) + return link + inAppIcon }, }, url: { @@ -158,12 +167,21 @@ const rules: MarkdownRules = { } }, html(node, output, state) { - return htmlTag( + const href = md.sanitizeUrl(node.target) as string + const link = htmlTag( 'a', output(node.content, state), { href: md.sanitizeUrl(node.target) as string, target: '_blank' }, state, ) + if (!state.openInApp) return link + const inAppIcon = htmlTag( + 'i', + '', + { class: 'open-in-app fas fa-arrow-right-to-bracket', 'data-href': href }, + state, + ) + return link + inAppIcon }, }, strike: { @@ -257,12 +275,16 @@ export default class extends Vue { @Prop({ required: true }) source!: string + @Prop({ default: false }) + openInApp!: boolean + render(h: any) { const state: MarkdownState = { inline: true, inQuote: false, escapeHTML: true, cssModuleNames: null, + openInApp: this.openInApp, } return h({ template: `
    ${htmlOutput(parser(this.source, state), state)}
    ` }) } diff --git a/client/src/components/settings.vue b/client/src/components/settings.vue index 080aaa4a..5857b2cd 100644 --- a/client/src/components/settings.vue +++ b/client/src/components/settings.vue @@ -35,6 +35,13 @@
  • +
  • + Always open Links in App + +
  • {{ $t('setting.keyboard_layout') }}