From 6c6df29ed3b76ee5f2e6ba43a6185ff66b91aace Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Fri, 13 Aug 2021 12:19:57 +0300 Subject: [PATCH 1/3] support richcontent in polls --- src/components/poll/poll.js | 10 +++++++--- src/components/poll/poll.vue | 6 ++---- src/components/status_content/status_content.vue | 2 +- .../entity_normalizer/entity_normalizer.service.js | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/components/poll/poll.js b/src/components/poll/poll.js index 98db5582e..a69b78861 100644 --- a/src/components/poll/poll.js +++ b/src/components/poll/poll.js @@ -1,10 +1,14 @@ -import Timeago from '../timeago/timeago.vue' +import Timeago from 'components/timeago/timeago.vue' +import RichContent from 'components/rich_content/rich_content.jsx' import { forEach, map } from 'lodash' export default { name: 'Poll', - props: ['basePoll'], - components: { Timeago }, + props: ['basePoll', 'emoji'], + components: { + Timeago, + RichContent + }, data () { return { loading: false, diff --git a/src/components/poll/poll.vue b/src/components/poll/poll.vue index 187d1829d..6e0234b3e 100644 --- a/src/components/poll/poll.vue +++ b/src/components/poll/poll.vue @@ -17,8 +17,7 @@ {{ percentageForOption(option.votes_count) }}% - - +
diff --git a/src/components/status_content/status_content.vue b/src/components/status_content/status_content.vue index 23c90913f..3f65e64ae 100644 --- a/src/components/status_content/status_content.vue +++ b/src/components/status_content/status_content.vue @@ -7,7 +7,7 @@ @parseReady="$emit('parseReady', $event)" >
- +
{ if (output.poll) { output.poll.options = (output.poll.options || []).map(field => ({ ...field, - title_html: addEmojis(escape(field.title), data.emojis) + title_html: escape(field.title) })) } output.pinned = data.pinned From 4c974f5ca21c6a514d0dfc09a0aeab7789da95c5 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Fri, 13 Aug 2021 13:06:42 +0300 Subject: [PATCH 2/3] richcontent support in polls, user cards and user profiles --- .../basic_user_card/basic_user_card.js | 4 +- .../basic_user_card/basic_user_card.vue | 12 +--- src/components/notification/notification.js | 4 +- src/components/notification/notification.scss | 2 + src/components/notification/notification.vue | 14 +++-- .../notifications/notifications.scss | 7 --- src/components/poll/poll.vue | 12 +++- src/components/rich_content/rich_content.scss | 1 + .../status_content/status_content.vue | 5 +- src/components/user_card/user_card.js | 4 +- src/components/user_card/user_card.vue | 61 +++++-------------- src/components/user_profile/user_profile.js | 4 +- src/components/user_profile/user_profile.vue | 20 +++--- .../entity_normalizer.service.js | 5 +- 14 files changed, 69 insertions(+), 86 deletions(-) diff --git a/src/components/basic_user_card/basic_user_card.js b/src/components/basic_user_card/basic_user_card.js index 87085a282..8f41e2fb0 100644 --- a/src/components/basic_user_card/basic_user_card.js +++ b/src/components/basic_user_card/basic_user_card.js @@ -1,5 +1,6 @@ import UserCard from '../user_card/user_card.vue' import UserAvatar from '../user_avatar/user_avatar.vue' +import RichContent from 'src/components/rich_content/rich_content.jsx' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' const BasicUserCard = { @@ -13,7 +14,8 @@ const BasicUserCard = { }, components: { UserCard, - UserAvatar + UserAvatar, + RichContent }, methods: { toggleUserExpanded () { diff --git a/src/components/basic_user_card/basic_user_card.vue b/src/components/basic_user_card/basic_user_card.vue index c53f6a9c7..53deb1df4 100644 --- a/src/components/basic_user_card/basic_user_card.vue +++ b/src/components/basic_user_card/basic_user_card.vue @@ -25,17 +25,11 @@ :title="user.name" class="basic-user-card-user-name" > - - - - {{ user.name }}
- + + + {{ percentageForOption(option.votes_count) }}% - +
diff --git a/src/components/rich_content/rich_content.scss b/src/components/rich_content/rich_content.scss index 12cb9776f..db08ef1ea 100644 --- a/src/components/rich_content/rich_content.scss +++ b/src/components/rich_content/rich_content.scss @@ -49,6 +49,7 @@ } .emoji { + display: inline-block; width: var(--emoji-size, 32px); height: var(--emoji-size, 32px); } diff --git a/src/components/status_content/status_content.vue b/src/components/status_content/status_content.vue index 3f65e64ae..5cebc697e 100644 --- a/src/components/status_content/status_content.vue +++ b/src/components/status_content/status_content.vue @@ -7,7 +7,10 @@ @parseReady="$emit('parseReady', $event)" >
- +
- -
- -
- {{ user.name }} -
- -

- -

- {{ user.description }} -

@@ -281,9 +264,10 @@ .user-card { position: relative; - &:hover .Avatar { + &:hover { --_still-image-img-visibility: visible; --_still-image-canvas-visibility: hidden; + --_still-image-label-visibility: hidden; } .panel-heading { @@ -327,12 +311,12 @@ } } - p { - margin-bottom: 0; - } - &-bio { text-align: center; + display: block; + line-height: 18px; + padding: 1em; + margin: 0; a { color: $fallback--link; @@ -344,11 +328,6 @@ vertical-align: middle; max-width: 100%; max-height: 400px; - - &.emoji { - width: 32px; - height: 32px; - } } } @@ -450,13 +429,6 @@ // big one z-index: 1; - img { - width: 26px; - height: 26px; - vertical-align: middle; - object-fit: contain - } - .top-line { display: flex; } @@ -469,12 +441,7 @@ margin-right: 1em; font-size: 15px; - img { - object-fit: contain; - height: 16px; - width: 16px; - vertical-align: middle; - } + --emoji-size: 14px; } .bottom-line { diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js index c0b55a6ce..7a4756091 100644 --- a/src/components/user_profile/user_profile.js +++ b/src/components/user_profile/user_profile.js @@ -4,6 +4,7 @@ import FollowCard from '../follow_card/follow_card.vue' import Timeline from '../timeline/timeline.vue' import Conversation from '../conversation/conversation.vue' import TabSwitcher from 'src/components/tab_switcher/tab_switcher.js' +import RichContent from 'src/components/rich_content/rich_content.jsx' import List from '../list/list.vue' import withLoadMore from '../../hocs/with_load_more/with_load_more' import { library } from '@fortawesome/fontawesome-svg-core' @@ -164,7 +165,8 @@ const UserProfile = { FriendList, FollowCard, TabSwitcher, - Conversation + Conversation, + RichContent } } diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue index aef897ae2..726216ff0 100644 --- a/src/components/user_profile/user_profile.vue +++ b/src/components/user_profile/user_profile.vue @@ -20,20 +20,24 @@ :key="index" class="user-profile-field" > - { output.emoji = data.emojis output.name = data.display_name - output.name_html = addEmojis(escape(data.display_name), data.emojis) + output.name_html = escape(data.display_name) output.description = data.note - output.description_html = addEmojis(data.note, data.emojis) + // TODO cleanup this shit, output.description is overriden with source data + output.description_html = data.note output.fields = data.fields output.fields_html = data.fields.map(field => { From 97e86381c868fbd49a33e190722934dee698600d Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Fri, 13 Aug 2021 13:12:33 +0300 Subject: [PATCH 3/3] remove old emoji added, everything emoji-bearing uses RichContent now --- .../entity_normalizer.service.js | 14 +------ .../entity_normalizer.spec.js | 37 +------------------ 2 files changed, 3 insertions(+), 48 deletions(-) diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index d84e3422a..04bb45a4b 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -65,8 +65,8 @@ export const parseUser = (data) => { output.fields = data.fields output.fields_html = data.fields.map(field => { return { - name: addEmojis(escape(field.name), data.emojis), - value: addEmojis(field.value, data.emojis) + name: escape(field.name), + value: field.value } }) output.fields_text = data.fields.map(field => { @@ -241,16 +241,6 @@ export const parseAttachment = (data) => { return output } -export const addEmojis = (string, emojis) => { - const matchOperatorsRegex = /[|\\{}()[\]^$+*?.-]/g - return emojis.reduce((acc, emoji) => { - const regexSafeShortCode = emoji.shortcode.replace(matchOperatorsRegex, '\\$&') - return acc.replace( - new RegExp(`:${regexSafeShortCode}:`, 'g'), - `:${emoji.shortcode}:` - ) - }, string) -} export const parseStatus = (data) => { const output = {} 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 8a5a6ef90..8932bc7c4 100644 --- a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js +++ b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js @@ -1,4 +1,4 @@ -import { parseStatus, parseUser, parseNotification, addEmojis, parseLinkHeaderPagination } from '../../../../../src/services/entity_normalizer/entity_normalizer.service.js' +import { parseStatus, parseUser, parseNotification, parseLinkHeaderPagination } from '../../../../../src/services/entity_normalizer/entity_normalizer.service.js' import mastoapidata from '../../../../fixtures/mastoapi.json' import qvitterapidata from '../../../../fixtures/statuses.json' @@ -338,41 +338,6 @@ describe('API Entities normalizer', () => { }) }) - describe('MastoAPI emoji adder', () => { - const emojis = makeMockEmojiMasto() - const imageHtml = ':image:' - .replace(/"/g, '\'') - const thinkHtml = ':thinking:' - .replace(/"/g, '\'') - - it('correctly replaces shortcodes in supplied string', () => { - const result = addEmojis('This post has :image: emoji and :thinking: emoji', emojis) - expect(result).to.include(thinkHtml) - expect(result).to.include(imageHtml) - }) - - it('handles consecutive emojis correctly', () => { - const result = addEmojis('Lelel emoji spam :thinking::thinking::thinking::thinking:', emojis) - expect(result).to.include(thinkHtml + thinkHtml + thinkHtml + thinkHtml) - }) - - it('Doesn\'t replace nonexistent emojis', () => { - const result = addEmojis('Admin add the :tenshi: emoji', emojis) - expect(result).to.equal('Admin add the :tenshi: emoji') - }) - - it('Doesn\'t blow up on regex special characters', () => { - const emojis = makeMockEmojiMasto([{ - shortcode: 'c++' - }, { - shortcode: '[a-z] {|}*' - }]) - const result = addEmojis('This post has :c++: emoji and :[a-z] {|}*: emoji', emojis) - expect(result).to.include('title=\':c++:\'') - expect(result).to.include('title=\':[a-z] {|}*:\'') - }) - }) - describe('Link header pagination', () => { it('Parses min and max ids as integers', () => { const linkHeader = '; rel="next", ; rel="prev"'