From 0924907c64376249433e2fd16278662181c9e856 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 27 Jan 2019 13:47:30 +0000 Subject: add link-preview component --- src/components/status/status.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/components/status/status.js') diff --git a/src/components/status/status.js b/src/components/status/status.js index b14a74ec..681d0373 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -5,6 +5,7 @@ import DeleteButton from '../delete_button/delete_button.vue' import PostStatusForm from '../post_status_form/post_status_form.vue' import UserCardContent from '../user_card_content/user_card_content.vue' import StillImage from '../still-image/still-image.vue' +import LinkPreview from '../link-preview/link-preview.vue' import { filter, find } from 'lodash' import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' @@ -220,7 +221,8 @@ const Status = { DeleteButton, PostStatusForm, UserCardContent, - StillImage + StillImage, + LinkPreview }, methods: { visibilityIcon (visibility) { -- cgit v1.2.3-70-g09d2 From 0460728a8c571b9a4468c2f93a2f8465fe37fa86 Mon Sep 17 00:00:00 2001 From: shpuld Date: Mon, 28 Jan 2019 21:59:17 +0200 Subject: Fix tall status expanding needing extra clicks, make tall status expand automatically in conversation when focused --- src/components/status/status.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src/components/status/status.js') diff --git a/src/components/status/status.js b/src/components/status/status.js index 13e79dd0..c93580c0 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -31,7 +31,7 @@ const Status = { userExpanded: false, preview: null, showPreview: false, - showingTall: false, + showingTall: this.inConversation && this.focused, expandingSubject: typeof this.$store.state.config.collapseMessageWithSubject === 'undefined' ? !this.$store.state.instance.collapseMessageWithSubject : !this.$store.state.config.collapseMessageWithSubject, @@ -262,13 +262,14 @@ const Status = { this.userExpanded = !this.userExpanded }, toggleShowMore () { + console.log('toggleShowMore', this.showingTall) if (this.showingTall) { this.showingTall = false - } else if (this.expandingSubject) { + } else if (this.expandingSubject && this.status.summary) { this.expandingSubject = false } else if (this.hideTallStatus) { this.showingTall = true - } else if (this.hideSubjectStatus) { + } else if (this.hideSubjectStatus && this.status.summary) { this.expandingSubject = true } }, @@ -301,8 +302,10 @@ const Status = { 'highlight': function (id) { if (this.status.id === id) { let rect = this.$el.getBoundingClientRect() - if (rect.top < 100) { + if (rect.top < 140) { window.scrollBy(0, rect.top - 200) + } else if (rect.top < window.innerHeight && rect.height >= (window.innerHeight - 50)) { + window.scrollBy(0, rect.top - 50) } else if (rect.bottom > window.innerHeight - 50) { window.scrollBy(0, rect.bottom - window.innerHeight + 50) } -- cgit v1.2.3-70-g09d2 From c3a931610a16a23659edc1140573a003e14c8dbc Mon Sep 17 00:00:00 2001 From: shpuld Date: Mon, 28 Jan 2019 22:03:25 +0200 Subject: remove log --- src/components/status/status.js | 1 - 1 file changed, 1 deletion(-) (limited to 'src/components/status/status.js') diff --git a/src/components/status/status.js b/src/components/status/status.js index c93580c0..443e6b42 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -262,7 +262,6 @@ const Status = { this.userExpanded = !this.userExpanded }, toggleShowMore () { - console.log('toggleShowMore', this.showingTall) if (this.showingTall) { this.showingTall = false } else if (this.expandingSubject && this.status.summary) { -- cgit v1.2.3-70-g09d2 From 0a39159fdf99143ddf05580f066508e6d5a90773 Mon Sep 17 00:00:00 2001 From: shpuld Date: Wed, 30 Jan 2019 16:38:28 +0200 Subject: Adjust scrolling logic and document it, make sure to never show 'show less' if it's not a tall status --- src/components/status/status.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src/components/status/status.js') diff --git a/src/components/status/status.js b/src/components/status/status.js index 558125df..6ef13010 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -179,7 +179,7 @@ const Status = { return this.tallStatus }, showingMore () { - return this.showingTall || (this.status.summary && this.expandingSubject) + return (this.tallStatus && this.showingTall) || (this.status.summary && this.expandingSubject) }, nsfwClickthrough () { if (!this.status.nsfw) { @@ -303,11 +303,14 @@ const Status = { 'highlight': function (id) { if (this.status.id === id) { let rect = this.$el.getBoundingClientRect() - if (rect.top < 140) { - window.scrollBy(0, rect.top - 200) - } else if (rect.top < window.innerHeight && rect.height >= (window.innerHeight - 50)) { - window.scrollBy(0, rect.top - 50) + if (rect.top < 100) { + // Post is above screen, match its top to screen top + window.scrollBy(0, rect.top - 100) + } else if (rect.height >= (window.innerHeight - 50)) { + // Post we want to see is taller than screen so match its top to screen top + window.scrollBy(0, rect.top - 100) } else if (rect.bottom > window.innerHeight - 50) { + // Post is below screen, match its bottom to screen bottom window.scrollBy(0, rect.bottom - window.innerHeight + 50) } } -- cgit v1.2.3-70-g09d2 From 16a5272726ec555d49276e291caa1d0ba71200e4 Mon Sep 17 00:00:00 2001 From: shpuld Date: Wed, 30 Jan 2019 16:57:19 +0200 Subject: Fix a simple typo --- src/components/status/status.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/components/status/status.js') diff --git a/src/components/status/status.js b/src/components/status/status.js index 558125df..f85b7847 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -79,7 +79,7 @@ const Status = { }, replyProfileLink () { if (this.isReply) { - return this.generateUserProfileLink(this.status.in_reply_to_status_id, this.replyToName) + return this.generateUserProfileLink(this.status.in_reply_to_user_id, this.replyToName) } }, retweet () { return !!this.statusoid.retweeted_status }, -- cgit v1.2.3-70-g09d2 From 15603981f8309d979465c40175f9b3cd4f6617b4 Mon Sep 17 00:00:00 2001 From: shpuld Date: Wed, 30 Jan 2019 19:15:35 +0200 Subject: Capture clicks on statuses to hijack mention clicks, match mention href to user somehow --- src/components/status/status.js | 15 +++++- src/components/status/status.vue | 4 +- src/services/mention_matcher/mention_matcher.js | 9 ++++ .../mention_matcher/mention_matcher.spec.js | 63 ++++++++++++++++++++++ 4 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 src/services/mention_matcher/mention_matcher.js create mode 100644 test/unit/specs/services/mention_matcher/mention_matcher.spec.js (limited to 'src/components/status/status.js') diff --git a/src/components/status/status.js b/src/components/status/status.js index 558125df..e268ddaa 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -9,6 +9,7 @@ import LinkPreview from '../link-preview/link-preview.vue' import { filter, find } from 'lodash' import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' +import { mentionMatchesUrl } from 'src/services/mention_matcher/mention_matcher.js' const Status = { name: 'Status', @@ -237,11 +238,23 @@ const Status = { return 'icon-globe' } }, - linkClicked ({target}) { + linkClicked (event) { + let { target } = event if (target.tagName === 'SPAN') { target = target.parentNode } if (target.tagName === 'A') { + if (target.className.match(/mention/)) { + const href = target.getAttribute('href') + const attn = this.status.attentions.find(attn => mentionMatchesUrl(attn, href)) + if (attn) { + event.stopPropagation() + event.preventDefault() + const link = this.generateUserProfileLink(attn.id, attn.screen_name) + this.$router.push(link) + return + } + } window.open(target.href, '_blank') } }, diff --git a/src/components/status/status.vue b/src/components/status/status.vue index d88428c7..45100a46 100644 --- a/src/components/status/status.vue +++ b/src/components/status/status.vue @@ -24,9 +24,9 @@
- + - +
diff --git a/src/services/mention_matcher/mention_matcher.js b/src/services/mention_matcher/mention_matcher.js new file mode 100644 index 00000000..2c1ed970 --- /dev/null +++ b/src/services/mention_matcher/mention_matcher.js @@ -0,0 +1,9 @@ + +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/mention_matcher/mention_matcher.spec.js new file mode 100644 index 00000000..4f6f58ff --- /dev/null +++ b/test/unit/specs/services/mention_matcher/mention_matcher.spec.js @@ -0,0 +1,63 @@ +import * as MentionMatcher from 'src/services/mention_matcher/mention_matcher.js' + +const localAttn = () => ({ + id: 123, + is_local: true, + name: 'Guy', + screen_name: 'person', + statusnet_profile_url: 'https://instance.com/users/person' +}) + +const externalAttn = () => ({ + id: 123, + is_local: false, + name: 'Guy', + screen_name: 'person@instance.com', + statusnet_profile_url: 'https://instance.com/users/person' +}) + +describe('MentionMatcher', () => { + 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) + }) + + 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) + }) + + it('should match external pleroma mention', () => { + const attention = externalAttn() + const url = 'https://instance.com/users/person' + + expect(MentionMatcher.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) + }) + + it('should match external mastodon mention', () => { + const attention = externalAttn() + const url = 'https://instance.com/@person' + + expect(MentionMatcher.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) + }) + }) +}) -- cgit v1.2.3-70-g09d2