commit: 39494439d359fa058079c9325efdff244a7e7890
parent c3576211cbbf9ada109c0869dcf4e4fc7b3ef925
Author: Henry Jameson <me@hjkos.com>
Date: Mon, 23 Aug 2021 20:57:21 +0300
very minimalist hashtaglink implementation, also you can middle-click
mentions now.
Diffstat:
6 files changed, 75 insertions(+), 12 deletions(-)
diff --git a/src/components/hashtag_link/hashtag_link.js b/src/components/hashtag_link/hashtag_link.js
@@ -0,0 +1,36 @@
+import { extractTagFromUrl } from 'src/services/matcher/matcher.service.js'
+
+const HashtagLink = {
+ name: 'HashtagLink',
+ props: {
+ url: {
+ required: true,
+ type: String
+ },
+ content: {
+ required: true,
+ type: String
+ },
+ tag: {
+ required: false,
+ type: String,
+ default: ''
+ }
+ },
+ methods: {
+ onClick () {
+ const tag = this.tag || extractTagFromUrl(this.url)
+ if (tag) {
+ const link = this.generateTagLink(tag)
+ this.$router.push(link)
+ } else {
+ window.open(this.url, '_blank')
+ }
+ },
+ generateTagLink (tag) {
+ return `/tag/${tag}`
+ }
+ }
+}
+
+export default HashtagLink
diff --git a/src/components/hashtag_link/hashtag_link.scss b/src/components/hashtag_link/hashtag_link.scss
@@ -0,0 +1,6 @@
+.HashtagLink {
+ position: relative;
+ white-space: normal;
+ display: inline-block;
+ color: var(--link);
+}
diff --git a/src/components/hashtag_link/hashtag_link.vue b/src/components/hashtag_link/hashtag_link.vue
@@ -0,0 +1,19 @@
+<template>
+ <span
+ class="HashtagLink"
+ >
+ <!-- eslint-disable vue/no-v-html -->
+ <a
+ :href="url"
+ class="original"
+ target="_blank"
+ @click.prevent="onClick"
+ v-html="content"
+ />
+ <!-- eslint-enable vue/no-v-html -->
+ </span>
+</template>
+
+<script src="./hashtag_link.js"/>
+
+<style lang="scss" src="./hashtag_link.scss"/>
diff --git a/src/components/mention_link/mention_link.vue b/src/components/mention_link/mention_link.vue
@@ -17,8 +17,9 @@
:style="style"
:class="classnames"
>
- <button
+ <a
class="short button-unstyled"
+ :href="url"
@click.prevent="onClick"
>
<!-- eslint-disable vue/no-v-html -->
@@ -35,7 +36,7 @@
class="you"
>{{ $t('status.you') }}</span>
<!-- eslint-enable vue/no-v-html -->
- </button>
+ </a>
<span
v-if="userName !== userNameFull"
class="full popover-default"
diff --git a/src/components/rich_content/rich_content.jsx b/src/components/rich_content/rich_content.jsx
@@ -5,6 +5,7 @@ import { convertHtmlToTree } from 'src/services/html_converter/html_tree_convert
import { convertHtmlToLines } from 'src/services/html_converter/html_line_converter.service.js'
import StillImage from 'src/components/still-image/still-image.vue'
import MentionsLine, { MENTIONS_LIMIT } from 'src/components/mentions_line/mentions_line.vue'
+import HashtagLink from 'src/components/hashtag_link/hashtag_link.vue'
import './rich_content.scss'
@@ -83,13 +84,10 @@ export default Vue.component('RichContent', {
const renderHashtag = (attrs, children, encounteredTextReverse) => {
const linkData = getLinkData(attrs, children, tagsIndex++)
writtenTags.push(linkData)
- attrs.target = '_blank'
if (!encounteredTextReverse) {
lastTags.push(linkData)
}
- return <a {...{ attrs }}>
- { children.map(processItem) }
- </a>
+ return <HashtagLink {...{ props: linkData }}/>
}
const renderMention = (attrs, children) => {
@@ -211,7 +209,10 @@ export default Vue.component('RichContent', {
if (!this.handleLinks) break
const attrs = getAttrs(opener)
// should only be this
- if (attrs['class'] && attrs['class'].includes('hashtag')) {
+ if (
+ (attrs['class'] && attrs['class'].includes('hashtag')) || // Pleroma style
+ (attrs['rel'] === 'tag') // Mastodon style
+ ) {
return renderHashtag(attrs, children, encounteredTextReverse)
} else {
attrs.target = '_blank'
@@ -275,7 +276,7 @@ const getLinkData = (attrs, children, index) => {
return {
index,
url: attrs.href,
- hashtag: attrs['data-tag'],
+ tag: attrs['data-tag'],
content: flattenDeep(children).join(''),
textContent
}
diff --git a/test/unit/specs/components/rich_content.spec.js b/test/unit/specs/components/rich_content.spec.js
@@ -300,10 +300,10 @@ describe('RichContent', () => {
'<p>',
'<a href="http://macrochan.org/images/N/H/NHCMDUXJPPZ6M3Z2CQ6D2EBRSWGE7MZY.jpg" target="_blank">',
'NHCMDUXJPPZ6M3Z2CQ6D2EBRSWGE7MZY.jpg</a>',
- ' <a class="hashtag" data-tag="nou" href="https://shitposter.club/tag/nou" target="_blank">',
- '#nou</a>',
- ' <a class="hashtag" data-tag="screencap" href="https://shitposter.club/tag/screencap" target="_blank">',
- '#screencap</a>',
+ ' <hashtaglink-stub url="https://shitposter.club/tag/nou" content="#nou" tag="nou">',
+ '</hashtaglink-stub>',
+ ' <hashtaglink-stub url="https://shitposter.club/tag/screencap" content="#screencap" tag="screencap">',
+ '</hashtaglink-stub>',
' </p>'
].join('')