commit: c21b1cf89840297a781e6adc66cc195b8741cac6
parent 636dbdaba8375cb991368620419e2997df0f57a9
Author: Henry Jameson <me@hjkos.com>
Date: Mon, 14 Jun 2021 10:30:08 +0300
do the impossible, fix the unfixable
Diffstat:
8 files changed, 118 insertions(+), 41 deletions(-)
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 MentionLink from 'src/components/mention_link/mention_link.vue'
+import MentionsLine from 'src/components/mentions_line/mentions_line.vue'
import './rich_content.scss'
@@ -51,6 +52,11 @@ export default Vue.component('RichContent', {
required: false,
type: Boolean,
default: false
+ },
+ hideMentions: {
+ required: false,
+ type: Boolean,
+ default: false
}
},
// NEVER EVER TOUCH DATA INSIDE RENDER
@@ -64,6 +70,7 @@ export default Vue.component('RichContent', {
// unique index for vue "tag" property
let mentionIndex = 0
let tagsIndex = 0
+ let firstMentionReplaced = false
const renderImage = (tag) => {
return <StillImage
@@ -90,7 +97,12 @@ export default Vue.component('RichContent', {
writtenMentions.push(linkData)
if (!encounteredText) {
firstMentions.push(linkData)
- return ''
+ if (!firstMentionReplaced && !this.hideMentions) {
+ firstMentionReplaced = true
+ return <MentionsLine mentions={ firstMentions } />
+ } else {
+ return ''
+ }
} else {
return <MentionLink
url={attrs.href}
@@ -143,7 +155,7 @@ export default Vue.component('RichContent', {
if (firstMentions.length > 1 && lastMentions.length > 1) {
break
} else {
- return ''
+ return !this.hideMentions ? <MentionsLine mentions={lastMentions} /> : ''
}
} else {
break
diff --git a/src/components/status_body/status_body.js b/src/components/status_body/status_body.js
@@ -1,6 +1,5 @@
import fileType from 'src/services/file_type/file_type.service'
import RichContent from 'src/components/rich_content/rich_content.jsx'
-import MentionsLine from 'src/components/mentions_line/mentions_line.vue'
import { mapGetters } from 'vuex'
import { library } from '@fortawesome/fontawesome-svg-core'
import { set } from 'vue'
@@ -36,9 +35,6 @@ const StatusContent = {
showingLongSubject: false,
// not as computed because it sets the initial state which will be changed later
expandingSubject: !this.$store.getters.mergedConfig.collapseMessageWithSubject,
- headTailLinks: null,
- firstMentions: [],
- lastMentions: []
}
},
computed: {
@@ -81,8 +77,7 @@ const StatusContent = {
...mapGetters(['mergedConfig'])
},
components: {
- RichContent,
- MentionsLine
+ RichContent
},
mounted () {
this.status.attentions && this.status.attentions.forEach(attn => {
@@ -98,11 +93,6 @@ const StatusContent = {
this.expandingSubject = !this.expandingSubject
}
},
- setHeadTailLinks (headTailLinks) {
- set(this, 'headTailLinks', headTailLinks)
- set(this, 'firstMentions', headTailLinks.firstMentions)
- set(this, 'lastMentions', headTailLinks.lastMentions)
- },
generateTagLink (tag) {
return `/tag/${tag}`
}
diff --git a/src/components/status_body/status_body.scss b/src/components/status_body/status_body.scss
@@ -62,7 +62,7 @@
overflow-y: hidden;
z-index: 1;
- .rich-content-wrapper {
+ .media-body {
min-height: 0;
mask:
linear-gradient(to top, white, transparent) bottom/100% 70px no-repeat,
diff --git a/src/components/status_body/status_body.vue b/src/components/status_body/status_body.vue
@@ -38,28 +38,17 @@
>
{{ $t("general.show_more") }}
</button>
- <span
+ <RichContent
v-if="!hideSubjectStatus && !(singleLine && status.summary_raw_html)"
- class="rich-content-wrapper"
- >
- <MentionsLine
- v-if="!hideMentions && firstMentions && firstMentions.length > 0"
- :mentions="firstMentions"
- />
- <RichContent
- :class="{ '-single-line': singleLine }"
- class="text media-body"
- :html="status.raw_html"
- :emoji="status.emojis"
- :handle-links="true"
- :greentext="mergedConfig.greentext"
- @parseReady="setHeadTailLinks"
- />
- <MentionsLine
- v-if="!hideMentions && lastMentions.length > 1 && firstMentions.length <= 1"
- :mentions="lastMentions"
- />
- </span>
+ :class="{ '-single-line': singleLine }"
+ class="text media-body"
+ :html="status.raw_html"
+ :emoji="status.emojis"
+ :handle-links="true"
+ :hide-mentions="hideMentions"
+ :greentext="mergedConfig.greentext"
+ @parseReady="$emit('parseReady', $event)"
+ />
<button
v-if="hideSubjectStatus"
diff --git a/src/components/status_content/status_content.js b/src/components/status_content/status_content.js
@@ -92,9 +92,6 @@ const StatusContent = {
StatusBody
},
methods: {
- setHeadTailLinks (headTailLinks) {
- this.$emit('parseReady', headTailLinks)
- },
setMedia () {
const attachments = this.attachmentSize === 'hide' ? this.status.attachments : this.galleryAttachments
return () => this.$store.dispatch('setMedia', attachments)
diff --git a/src/components/status_content/status_content.vue b/src/components/status_content/status_content.vue
@@ -5,7 +5,7 @@
:status="status"
:single-line="singleLine"
:hide-mentions="hideMentions"
- @parseReady="setHeadTailLinks"
+ @parseReady="$emit('parseReady', $event)"
>
<div v-if="status.poll && status.poll.options">
<poll :base-poll="status.poll" />
diff --git a/test/unit/specs/components/rich_content.spec.js b/test/unit/specs/components/rich_content.spec.js
@@ -16,6 +16,7 @@ describe('RichContent', () => {
const wrapper = shallowMount(RichContent, {
localVue,
propsData: {
+ hideMentions: true,
handleLinks: true,
greentext: true,
emoji: [],
@@ -38,6 +39,34 @@ describe('RichContent', () => {
const wrapper = shallowMount(RichContent, {
localVue,
propsData: {
+ hideMentions: true,
+ handleLinks: true,
+ greentext: true,
+ emoji: [],
+ html
+ }
+ })
+
+ expect(wrapper.html()).to.eql(compwrap(expected))
+ })
+
+ it('replaces first mention with mentionsline if hideMentions=false', () => {
+ const html = p(
+ makeMention('John'),
+ ' how are you doing thoday?'
+ )
+ const expected = p(
+ '<span class="h-card">',
+ '<mentionsline-stub mentions="',
+ '[object Object]',
+ '"></mentionsline-stub>',
+ '</span>',
+ 'how are you doing thoday?'
+ )
+ const wrapper = shallowMount(RichContent, {
+ localVue,
+ propsData: {
+ hideMentions: false,
handleLinks: true,
greentext: true,
emoji: [],
@@ -68,6 +97,7 @@ describe('RichContent', () => {
const wrapper = shallowMount(RichContent, {
localVue,
propsData: {
+ hideMentions: true,
handleLinks: true,
greentext: true,
emoji: [],
@@ -78,6 +108,44 @@ describe('RichContent', () => {
expect(wrapper.html()).to.eql(compwrap(expected))
})
+ it('replaces mentions at the end of the hellpost if hideMentions=false (<p>)', () => {
+ const html = [
+ p('How are you doing today, fine gentlemen?'),
+ p(
+ makeMention('John'),
+ makeMention('Josh'),
+ makeMention('Jeremy')
+ )
+ ].join('')
+ const expected = [
+ p(
+ 'How are you doing today, fine gentlemen?'
+ ),
+ // TODO fix this extra line somehow?
+ p(
+ '<mentionsline-stub mentions="',
+ '[object Object],',
+ '[object Object],',
+ '[object Object]',
+ '"></mentionsline-stub>'
+ )
+ ].join('')
+
+ const wrapper = shallowMount(RichContent, {
+ localVue,
+ propsData: {
+ hideMentions: false,
+ handleLinks: true,
+ greentext: true,
+ emoji: [],
+ html
+ }
+ })
+
+ expect(wrapper.html()).to.eql(compwrap(expected))
+ })
+
+
it('removes mentions from the end of the hellpost (<br>)', () => {
const html = [
'How are you doing today, fine gentlemen?',
@@ -96,6 +164,7 @@ describe('RichContent', () => {
const wrapper = shallowMount(RichContent, {
localVue,
propsData: {
+ hideMentions: true,
handleLinks: true,
greentext: true,
emoji: [],
@@ -124,6 +193,7 @@ describe('RichContent', () => {
const wrapper = shallowMount(RichContent, {
localVue,
propsData: {
+ hideMentions: true,
handleLinks: true,
greentext: true,
emoji: [],
@@ -165,6 +235,7 @@ describe('RichContent', () => {
const wrapper = shallowMount(RichContent, {
localVue,
propsData: {
+ hideMentions: true,
handleLinks: true,
greentext: true,
emoji: [],
@@ -199,6 +270,7 @@ describe('RichContent', () => {
const wrapper = shallowMount(RichContent, {
localVue,
propsData: {
+ hideMentions: true,
handleLinks: true,
greentext: true,
emoji: [],
@@ -240,6 +312,7 @@ describe('RichContent', () => {
const wrapper = shallowMount(RichContent, {
localVue,
propsData: {
+ hideMentions: true,
handleLinks: true,
greentext: true,
emoji: [],
@@ -267,6 +340,7 @@ describe('RichContent', () => {
const wrapper = shallowMount(RichContent, {
localVue,
propsData: {
+ hideMentions: true,
handleLinks: false,
greentext: true,
emoji: [],
@@ -290,6 +364,7 @@ describe('RichContent', () => {
const wrapper = shallowMount(RichContent, {
localVue,
propsData: {
+ hideMentions: true,
handleLinks: false,
greentext: true,
emoji: [],
@@ -309,6 +384,7 @@ describe('RichContent', () => {
const wrapper = shallowMount(RichContent, {
localVue,
propsData: {
+ hideMentions: true,
handleLinks: false,
greentext: false,
emoji: [],
@@ -329,6 +405,7 @@ describe('RichContent', () => {
const wrapper = shallowMount(RichContent, {
localVue,
propsData: {
+ hideMentions: true,
handleLinks: false,
greentext: false,
emoji: [{ url: 'about:blank', shortcode: 'spurdo' }],
@@ -345,6 +422,7 @@ describe('RichContent', () => {
const wrapper = shallowMount(RichContent, {
localVue,
propsData: {
+ hideMentions: true,
handleLinks: false,
greentext: false,
emoji: [],
@@ -407,6 +485,7 @@ describe('RichContent', () => {
const wrapper = shallowMount(RichContent, {
localVue,
propsData: {
+ hideMentions: true,
handleLinks: true,
greentext: true,
emoji: [],
@@ -425,10 +504,18 @@ describe('RichContent', () => {
makeMention('bar'),
makeMention('baz')
].join('<br>')
+ const expected = [
+ 'Bruh',
+ 'Bruh',
+ stubMention('foo'),
+ stubMention('bar'),
+ stubMention('baz')
+ ].join('<br>')
const wrapper = shallowMount(RichContent, {
localVue,
propsData: {
+ hideMentions: true,
handleLinks: true,
greentext: true,
emoji: [],
@@ -436,7 +523,7 @@ describe('RichContent', () => {
}
})
- expect(wrapper.html()).to.eql(compwrap(html))
+ expect(wrapper.html()).to.eql(compwrap(expected))
})
it('Don\'t remove last mentions if there are more than one first mention - remove first instead', () => {
@@ -471,6 +558,7 @@ describe('RichContent', () => {
const wrapper = shallowMount(RichContent, {
localVue,
propsData: {
+ hideMentions: true,
handleLinks: true,
greentext: true,
emoji: [],
@@ -506,6 +594,7 @@ describe('RichContent', () => {
const wrapper = shallowMount(RichContent, {
localVue,
propsData: {
+ hideMentions: true,
handleLinks: true,
greentext: true,
emoji: [],
diff --git a/test/unit/specs/services/html_converter/html_line_converter.spec.js b/test/unit/specs/services/html_converter/html_line_converter.spec.js
@@ -11,7 +11,7 @@ const mapOnlyText = (processor) => (input) => {
}
}
-describe.only('html_line_converter', () => {
+describe('html_line_converter', () => {
describe('with processor that keeps original line should not make any changes to HTML when', () => {
const processorKeep = (line) => line
it('fed with regular HTML with newlines', () => {