From a12397cf387da7d411184a72f9c128ba6486a631 Mon Sep 17 00:00:00 2001 From: Edijs Date: Wed, 6 Feb 2019 11:34:21 -0700 Subject: [PATCH 1/7] Hashtag opens in same tab --- src/components/status/status.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/components/status/status.js b/src/components/status/status.js index 65ddcb9f..cccb19cc 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -282,8 +282,15 @@ const Status = { this.$router.push(link) return } + } else { + if (target.hostname === window.location.hostname) { + // if the hashtag's target is current instance, open in same tab + this.$router.push(target.pathname) + } else { + // if it is different instance, open in a new tab + window.open(target.href, '_blank') + } } - window.open(target.href, '_blank') } }, toggleReplying () { From a215f6856d0dff53869a4c20e538eb744b636a4d Mon Sep 17 00:00:00 2001 From: Edijs Date: Wed, 6 Feb 2019 21:26:32 -0700 Subject: [PATCH 2/7] Always open tag in same instance --- src/components/status/status.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/components/status/status.js b/src/components/status/status.js index cccb19cc..1ebb8a8d 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -283,13 +283,7 @@ const Status = { return } } else { - if (target.hostname === window.location.hostname) { - // if the hashtag's target is current instance, open in same tab - this.$router.push(target.pathname) - } else { - // if it is different instance, open in a new tab - window.open(target.href, '_blank') - } + this.$router.push(target.pathname) } } }, From c0b833cb85ccd10942accbefc3ba4d70cf3d745e Mon Sep 17 00:00:00 2001 From: Edijs Date: Thu, 7 Feb 2019 14:46:10 -0700 Subject: [PATCH 3/7] Added tag extractor method and spec --- src/services/matcher/matcher.service.js | 23 ++++++++++++ .../mention_matcher/mention_matcher.js | 9 ----- .../matcher.spec.js} | 35 ++++++++++++++----- 3 files changed, 50 insertions(+), 17 deletions(-) create mode 100644 src/services/matcher/matcher.service.js delete mode 100644 src/services/mention_matcher/mention_matcher.js rename test/unit/specs/services/{mention_matcher/mention_matcher.spec.js => matcher/matcher.spec.js} (57%) diff --git a/src/services/matcher/matcher.service.js b/src/services/matcher/matcher.service.js new file mode 100644 index 00000000..b6c4e909 --- /dev/null +++ b/src/services/matcher/matcher.service.js @@ -0,0 +1,23 @@ +export const mentionMatchesUrl = (attention, url) => { + if (url === attention.statusnet_profile_url) { + return true + } + const [namepart, instancepart] = attention.screen_name.split('@') + const matchstring = new RegExp('://' + instancepart + '/.*' + namepart + '$', 'g') + + return !!url.match(matchstring) +} + +/** + * Extract tag name from pleroma or mastodon url. + * i.e https://bikeshed.party/tag/photo or https://quey.org/tags/sky + * @param {string} url + */ +export const extractTagFromUrl = (url) => { + const regex = /tag[s]*\/(\w+)$/g + const result = regex.exec(url) + if (!result) { + return false + } + return result[1] +} diff --git a/src/services/mention_matcher/mention_matcher.js b/src/services/mention_matcher/mention_matcher.js deleted file mode 100644 index 2c1ed970..00000000 --- a/src/services/mention_matcher/mention_matcher.js +++ /dev/null @@ -1,9 +0,0 @@ - -export const mentionMatchesUrl = (attention, url) => { - if (url === attention.statusnet_profile_url) { - return true - } - const [namepart, instancepart] = attention.screen_name.split('@') - const matchstring = new RegExp('://' + instancepart + '/.*' + namepart + '$', 'g') - return !!url.match(matchstring) -} diff --git a/test/unit/specs/services/mention_matcher/mention_matcher.spec.js b/test/unit/specs/services/matcher/matcher.spec.js similarity index 57% rename from test/unit/specs/services/mention_matcher/mention_matcher.spec.js rename to test/unit/specs/services/matcher/matcher.spec.js index 4f6f58ff..0b5363b4 100644 --- a/test/unit/specs/services/mention_matcher/mention_matcher.spec.js +++ b/test/unit/specs/services/matcher/matcher.spec.js @@ -1,4 +1,4 @@ -import * as MentionMatcher from 'src/services/mention_matcher/mention_matcher.js' +import * as MatcherService from 'src/services/matcher/matcher.service.js' const localAttn = () => ({ id: 123, @@ -16,48 +16,67 @@ const externalAttn = () => ({ statusnet_profile_url: 'https://instance.com/users/person' }) -describe('MentionMatcher', () => { +describe('MatcherService', () => { describe.only('mentionMatchesUrl', () => { it('should match local mention', () => { const attention = localAttn() const url = 'https://instance.com/users/person' - expect(MentionMatcher.mentionMatchesUrl(attention, url)).to.eql(true) + expect(MatcherService.mentionMatchesUrl(attention, url)).to.eql(true) }) it('should not match a local mention with same name but different instance', () => { const attention = localAttn() const url = 'https://website.com/users/person' - expect(MentionMatcher.mentionMatchesUrl(attention, url)).to.eql(false) + expect(MatcherService.mentionMatchesUrl(attention, url)).to.eql(false) }) it('should match external pleroma mention', () => { const attention = externalAttn() const url = 'https://instance.com/users/person' - expect(MentionMatcher.mentionMatchesUrl(attention, url)).to.eql(true) + expect(MatcherService.mentionMatchesUrl(attention, url)).to.eql(true) }) it('should not match external pleroma mention with same name but different instance', () => { const attention = externalAttn() const url = 'https://website.com/users/person' - expect(MentionMatcher.mentionMatchesUrl(attention, url)).to.eql(false) + expect(MatcherService.mentionMatchesUrl(attention, url)).to.eql(false) }) it('should match external mastodon mention', () => { const attention = externalAttn() const url = 'https://instance.com/@person' - expect(MentionMatcher.mentionMatchesUrl(attention, url)).to.eql(true) + expect(MatcherService.mentionMatchesUrl(attention, url)).to.eql(true) }) it('should not match external mastodon mention with same name but different instance', () => { const attention = externalAttn() const url = 'https://website.com/@person' - expect(MentionMatcher.mentionMatchesUrl(attention, url)).to.eql(false) + expect(MatcherService.mentionMatchesUrl(attention, url)).to.eql(false) + }) + }) + describe.only('extractTagFromUrl', () => { + it('should return tag name from valid pleroma url', () => { + const url = 'https://website.com/tag/photo' + + expect(MatcherService.extractTagFromUrl(url)).to.eql('photo') + }) + + it('should return tag name from valid mastodon url', () => { + const url = 'https://website.com/tags/sky' + + expect(MatcherService.extractTagFromUrl(url)).to.eql('sky') + }) + + it('should not return string but false if invalid url', () => { + const url = 'https://website.com/users/sky' + + expect(MatcherService.extractTagFromUrl(url)).to.eql(false) }) }) }) From e44d8ad71eb1128ae53bfdd47ac81d3aa5d8ae07 Mon Sep 17 00:00:00 2001 From: Edijs Date: Thu, 7 Feb 2019 14:54:49 -0700 Subject: [PATCH 4/7] Extract tag name from href and open in same tab --- src/components/status/status.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/components/status/status.js b/src/components/status/status.js index 1ebb8a8d..a3b662b6 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -10,7 +10,7 @@ import LinkPreview from '../link-preview/link-preview.vue' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import fileType from 'src/services/file_type/file_type.service' import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js' -import { mentionMatchesUrl } from 'src/services/mention_matcher/mention_matcher.js' +import { mentionMatchesUrl, extractTagFromUrl } from 'src/services/matcher/matcher.service.js' import { filter, find } from 'lodash' const Status = { @@ -273,7 +273,7 @@ const Status = { } if (target.tagName === 'A') { if (target.className.match(/mention/)) { - const href = target.getAttribute('href') + const href = target.href const attn = this.status.attentions.find(attn => mentionMatchesUrl(attn, href)) if (attn) { event.stopPropagation() @@ -282,8 +282,14 @@ const Status = { this.$router.push(link) return } - } else { - this.$router.push(target.pathname) + } + if (target.className.match(/hashtag/)) { + // Extract tag name from link url + const tag = extractTagFromUrl(target.href) + if (tag) { + const link = this.generateTagLink(tag) + this.$router.push(link) + } } } }, @@ -340,6 +346,9 @@ const Status = { generateUserProfileLink (id, name) { return generateProfileLink(id, name, this.$store.state.instance.restrictedNicknames) }, + generateTagLink (tag) { + return `/tag/${tag}` + }, setMedia () { const attachments = this.attachmentSize === 'hide' ? this.status.attachments : this.galleryAttachments return () => this.$store.dispatch('setMedia', attachments) From d39e2643f523e84cdce1945538149a9bd6419fd6 Mon Sep 17 00:00:00 2001 From: Edijs Date: Thu, 7 Feb 2019 14:56:00 -0700 Subject: [PATCH 5/7] Fix lint warning --- src/components/status/status.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/status/status.vue b/src/components/status/status.vue index 9986107f..779696ea 100644 --- a/src/components/status/status.vue +++ b/src/components/status/status.vue @@ -57,7 +57,7 @@

Replies: - + {{reply.name}} 

From 7addd408a9fa7f3a3d7966e050feaa162c8f6a5c Mon Sep 17 00:00:00 2001 From: Edijs Date: Sun, 10 Feb 2019 12:06:13 -0700 Subject: [PATCH 6/7] Typo --- test/unit/specs/services/matcher/matcher.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/specs/services/matcher/matcher.spec.js b/test/unit/specs/services/matcher/matcher.spec.js index 0b5363b4..7a2494f0 100644 --- a/test/unit/specs/services/matcher/matcher.spec.js +++ b/test/unit/specs/services/matcher/matcher.spec.js @@ -17,7 +17,7 @@ const externalAttn = () => ({ }) describe('MatcherService', () => { - describe.only('mentionMatchesUrl', () => { + describe('mentionMatchesUrl', () => { it('should match local mention', () => { const attention = localAttn() const url = 'https://instance.com/users/person' @@ -60,7 +60,7 @@ describe('MatcherService', () => { expect(MatcherService.mentionMatchesUrl(attention, url)).to.eql(false) }) }) - describe.only('extractTagFromUrl', () => { + describe('extractTagFromUrl', () => { it('should return tag name from valid pleroma url', () => { const url = 'https://website.com/tag/photo' From be77707381609e555c565f6ba187318562e57dcf Mon Sep 17 00:00:00 2001 From: Edijs Date: Sun, 10 Feb 2019 19:32:01 -0700 Subject: [PATCH 7/7] Fix unit test --- .../services/entity_normalizer/entity_normalizer.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js index 703fecf1..6245361c 100644 --- a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js +++ b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js @@ -241,7 +241,7 @@ describe('API Entities normalizer', () => { notice: makeMockStatusQvitter({ id: 444 }), from_profile: makeMockUserQvitter({ id: 'spurdo' }) }) - expect(parseNotification(notif)).to.have.property('id', '123') + expect(parseNotification(notif)).to.have.property('id', 123) expect(parseNotification(notif)).to.have.property('seen', false) expect(parseNotification(notif)).to.have.deep.property('status.id', '444') expect(parseNotification(notif)).to.have.deep.property('action.id', '444') @@ -259,7 +259,7 @@ describe('API Entities normalizer', () => { is_seen: 1, from_profile: makeMockUserQvitter({ id: 'spurdo' }) }) - expect(parseNotification(notif)).to.have.property('id', '123') + expect(parseNotification(notif)).to.have.property('id', 123) expect(parseNotification(notif)).to.have.property('type', 'like') expect(parseNotification(notif)).to.have.property('seen', true) expect(parseNotification(notif)).to.have.deep.property('status.id', '4412')