From 20ce6468520e76b0fb2931a5fac368157d950b1d Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 7 Jun 2021 03:14:48 +0300 Subject: [WIP] MUCH better approach to replacing emojis with still versions --- src/services/entity_normalizer/entity_normalizer.service.js | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/services/entity_normalizer/entity_normalizer.service.js') diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index a4ddf927..9f63feb6 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -267,6 +267,8 @@ export const parseStatus = (data) => { output.nsfw = data.sensitive output.statusnet_html = addEmojis(data.content, data.emojis) + output.raw_html = data.content + output.emojis = data.emojis output.tags = data.tags @@ -293,6 +295,7 @@ export const parseStatus = (data) => { output.retweeted_status = parseStatus(data.reblog) } + output.summary_raw_html = escape(data.spoiler_text) output.summary_html = addEmojis(escape(data.spoiler_text), data.emojis) output.external_url = data.url output.poll = data.poll -- cgit v1.2.3-70-g09d2 From 04fa1f0b2d1a92b1c653cd55f51ee7e1434b2bd7 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 7 Jun 2021 18:39:51 +0300 Subject: some docs, added richcontent to usernames in status, updated stillImage to allow scale of "gif" label --- src/components/rich_content/rich_content.jsx | 33 +++++++++++++++++----- src/components/rich_content/rich_content.scss | 4 +-- src/components/status/status.js | 7 +++-- src/components/status/status.scss | 8 ++---- src/components/status/status.vue | 12 ++++---- src/components/still-image/still-image.vue | 3 +- .../entity_normalizer/entity_normalizer.service.js | 1 + 7 files changed, 44 insertions(+), 24 deletions(-) (limited to 'src/services/entity_normalizer/entity_normalizer.service.js') diff --git a/src/components/rich_content/rich_content.jsx b/src/components/rich_content/rich_content.jsx index 00cf6623..c15877c8 100644 --- a/src/components/rich_content/rich_content.jsx +++ b/src/components/rich_content/rich_content.jsx @@ -9,25 +9,41 @@ import './rich_content.scss' export default Vue.component('RichContent', { name: 'RichContent', props: { + // Original html content html: { required: true, type: String }, + // Emoji object, as in status.emojis, note the "s" at the end... emoji: { required: true, type: Array + }, + // Whether to handle links or not (posts: yes, everything else: no) + handleLinks: { + required: false, + type: Boolean, + default: false } }, render (h) { const renderImage = (tag) => { - const attrs = getAttrs(tag) - return + return } const renderMention = (attrs, children) => { - return + return } - const structure = convertHtml(this.html) + + // Processor to use with mini_html_converter const processItem = (item) => { + // Handle text noes - just add emoji if (typeof item === 'string') { if (item.includes(':')) { return processTextForEmoji( @@ -46,18 +62,21 @@ export default Vue.component('RichContent', { return unescape(item) } } + // Handle tag nodes if (Array.isArray(item)) { const [opener, children] = item const Tag = getTagName(opener) switch (Tag) { - case 'img': + case 'img': // replace images with StillImage return renderImage(opener) - case 'a': + case 'a': // replace mentions with MentionLink + if (!this.handleLinks) break const attrs = getAttrs(opener) if (attrs['class'] && attrs['class'].includes('mention')) { return renderMention(attrs, children) } } + // Render tag as is if (children !== undefined) { return { children.map(processItem) } @@ -68,7 +87,7 @@ export default Vue.component('RichContent', { } } return - { structure.map(processItem) } + { convertHtml(this.html).map(processItem) } } }) diff --git a/src/components/rich_content/rich_content.scss b/src/components/rich_content/rich_content.scss index 2fcd3911..a486babf 100644 --- a/src/components/rich_content/rich_content.scss +++ b/src/components/rich_content/rich_content.scss @@ -56,8 +56,8 @@ } .emoji { - width: 32px; - height: 32px; + width: var(--emoji-size, 32px); + height: var(--emoji-size, 32px); } .img, diff --git a/src/components/status/status.js b/src/components/status/status.js index 470c01f1..b6414ad8 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -9,6 +9,7 @@ import UserAvatar from '../user_avatar/user_avatar.vue' import AvatarList from '../avatar_list/avatar_list.vue' import Timeago from '../timeago/timeago.vue' import StatusContent from '../status_content/status_content.vue' +import RichContent from 'src/components/rich_content/rich_content.jsx' import StatusPopover from '../status_popover/status_popover.vue' import UserListPopover from '../user_list_popover/user_list_popover.vue' import EmojiReactions from '../emoji_reactions/emoji_reactions.vue' @@ -68,7 +69,8 @@ const Status = { StatusPopover, UserListPopover, EmojiReactions, - StatusContent + StatusContent, + RichContent }, props: [ 'statusoid', @@ -136,8 +138,9 @@ const Status = { } }, retweet () { return !!this.statusoid.retweeted_status }, + retweeterUser () { return this.statusoid.user }, retweeter () { return this.statusoid.user.name || this.statusoid.user.screen_name_ui }, - retweeterHtml () { return this.statusoid.user.name_html }, + retweeterHtml () { return this.statusoid.user.name }, retweeterProfileLink () { return this.generateUserProfileLink(this.statusoid.user.id, this.statusoid.user.screen_name) }, status () { if (this.retweet) { diff --git a/src/components/status/status.scss b/src/components/status/status.scss index 58b55bc8..82088943 100644 --- a/src/components/status/status.scss +++ b/src/components/status/status.scss @@ -93,12 +93,8 @@ $status-margin: 0.75em; margin-right: 0.4em; text-overflow: ellipsis; - .emoji { - width: 14px; - height: 14px; - vertical-align: middle; - object-fit: contain; - } + --_still_image-label-scale: 0.25; + --emoji-size: 14px; } .status-favicon { diff --git a/src/components/status/status.vue b/src/components/status/status.vue index 00e962f3..cc5fb79f 100644 --- a/src/components/status/status.vue +++ b/src/components/status/status.vue @@ -1,5 +1,4 @@ - diff --git a/src/components/still-image/still-image.vue b/src/components/still-image/still-image.vue index d3eb5925..a3610b51 100644 --- a/src/components/still-image/still-image.vue +++ b/src/components/still-image/still-image.vue @@ -30,7 +30,7 @@ position: relative; line-height: 0; overflow: hidden; - display: flex; + display: inline-flex; align-items: center; canvas { @@ -53,6 +53,7 @@ &.animated { &::before { + zoom: var(--_still_image-label-scale, 1); content: 'gif'; position: absolute; line-height: 10px; diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index 9f63feb6..8dc22823 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -54,6 +54,7 @@ export const parseUser = (data) => { return output } + output.emoji = data.emojis output.name = data.display_name output.name_html = addEmojis(escape(data.display_name), data.emojis) -- cgit v1.2.3-70-g09d2 From 8e9f5d7580d5a248e280b110218aa23052827789 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 7 Jun 2021 19:50:26 +0300 Subject: renamed StatusText to StatusBody for clarity, fixed chats --- src/components/chat_list_item/chat_list_item.js | 9 +- src/components/chat_list_item/chat_list_item.scss | 9 +- src/components/chat_list_item/chat_list_item.vue | 3 +- src/components/chat_message/chat_message.js | 2 + src/components/chat_message/chat_message.scss | 6 +- src/components/chat_message/chat_message.vue | 1 + .../settings_modal/tabs/theme_tab/theme_tab.js | 2 +- src/components/status/status.vue | 10 +- src/components/status_body/status_body.js | 147 +++++++++++++++++++++ src/components/status_body/status_body.scss | 112 ++++++++++++++++ src/components/status_body/status_body.vue | 95 +++++++++++++ src/components/status_content/status_content.js | 4 +- src/components/status_content/status_content.vue | 102 +------------- src/components/status_text/status_text.js | 147 --------------------- src/components/status_text/status_text.vue | 95 ------------- .../entity_normalizer/entity_normalizer.service.js | 2 + .../mini_html_converter.service.js | 2 +- yarn.lock | 81 ++++++++++-- 18 files changed, 460 insertions(+), 369 deletions(-) create mode 100644 src/components/status_body/status_body.js create mode 100644 src/components/status_body/status_body.scss create mode 100644 src/components/status_body/status_body.vue delete mode 100644 src/components/status_text/status_text.js delete mode 100644 src/components/status_text/status_text.vue (limited to 'src/services/entity_normalizer/entity_normalizer.service.js') diff --git a/src/components/chat_list_item/chat_list_item.js b/src/components/chat_list_item/chat_list_item.js index bee1ad53..e01b9bd4 100644 --- a/src/components/chat_list_item/chat_list_item.js +++ b/src/components/chat_list_item/chat_list_item.js @@ -1,5 +1,5 @@ import { mapState } from 'vuex' -import StatusContent from '../status_content/status_content.vue' +import StatusBody from '../status_content/status_content.vue' import fileType from 'src/services/file_type/file_type.service' import UserAvatar from '../user_avatar/user_avatar.vue' import AvatarList from '../avatar_list/avatar_list.vue' @@ -16,7 +16,7 @@ const ChatListItem = { AvatarList, Timeago, ChatTitle, - StatusContent + StatusBody }, computed: { ...mapState({ @@ -38,12 +38,15 @@ const ChatListItem = { }, messageForStatusContent () { const message = this.chat.lastMessage + const messageEmojis = message ? message.emojis : [] const isYou = message && message.account_id === this.currentUser.id - const content = message ? (this.attachmentInfo || message.content) : '' + const content = message ? (this.attachmentInfo || message.content_raw) : '' const messagePreview = isYou ? `${this.$t('chats.you')} ${content}` : content return { summary: '', + emojis: messageEmojis, statusnet_html: messagePreview, + raw_html: messagePreview, text: messagePreview, attachments: [] } diff --git a/src/components/chat_list_item/chat_list_item.scss b/src/components/chat_list_item/chat_list_item.scss index 9e97b28e..57332bed 100644 --- a/src/components/chat_list_item/chat_list_item.scss +++ b/src/components/chat_list_item/chat_list_item.scss @@ -77,18 +77,15 @@ border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius); } - .StatusContent { - img.emoji { - width: 1.4em; - height: 1.4em; - } + .chat-preview-body { + --emoji-size: 1.4em; } .time-wrapper { line-height: 1.4em; } - .single-line { + .chat-preview-body { padding-right: 1em; } } diff --git a/src/components/chat_list_item/chat_list_item.vue b/src/components/chat_list_item/chat_list_item.vue index cd3f436e..c7c0e878 100644 --- a/src/components/chat_list_item/chat_list_item.vue +++ b/src/components/chat_list_item/chat_list_item.vue @@ -29,7 +29,8 @@
- diff --git a/src/components/chat_message/chat_message.js b/src/components/chat_message/chat_message.js index bb380f87..d126d453 100644 --- a/src/components/chat_message/chat_message.js +++ b/src/components/chat_message/chat_message.js @@ -57,6 +57,8 @@ const ChatMessage = { messageForStatusContent () { return { summary: '', + emojis: this.message.emojis, + raw_html: this.message.content_raw, statusnet_html: this.message.content, text: this.message.content, attachments: this.message.attachments diff --git a/src/components/chat_message/chat_message.scss b/src/components/chat_message/chat_message.scss index e4351d3b..220355ea 100644 --- a/src/components/chat_message/chat_message.scss +++ b/src/components/chat_message/chat_message.scss @@ -89,8 +89,9 @@ } .without-attachment { - .status-content { - &::after { + .message-content { + // TODO figure out how to do it properly + .text::after { margin-right: 5.4em; content: " "; display: inline-block; @@ -162,6 +163,7 @@ .visible { opacity: 1; } + } .chat-message-date-separator { diff --git a/src/components/chat_message/chat_message.vue b/src/components/chat_message/chat_message.vue index 0f3fc97d..d62b831d 100644 --- a/src/components/chat_message/chat_message.vue +++ b/src/components/chat_message/chat_message.vue @@ -71,6 +71,7 @@
diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.js b/src/components/settings_modal/tabs/theme_tab/theme_tab.js index 1388f74b..63416e93 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.js +++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.js @@ -474,7 +474,7 @@ export default { this.loadThemeFromLocalStorage(false, true) break case 'file': - console.err('Forcing snapshout from file is not supported yet') + console.error('Forcing snapshout from file is not supported yet') break } this.dismissWarning() diff --git a/src/components/status/status.vue b/src/components/status/status.vue index cc5fb79f..a4247cd4 100644 --- a/src/components/status/status.vue +++ b/src/components/status/status.vue @@ -89,7 +89,10 @@ v-if="retweeterHtml" :to="retweeterProfileLink" > - + - +

for paragraphs, GS uses
between them) + // as well as approximate line count by counting characters and approximating ~80 + // per line. + // + // Using max-height + overflow: auto for status components resulted in false positives + // very often with japanese characters, and it was very annoying. + tallStatus () { + const lengthScore = this.status.statusnet_html.split(/ 20 + }, + longSubject () { + return this.status.summary.length > 240 + }, + // When a status has a subject and is also tall, we should only have one show more/less button. If the default is to collapse statuses with subjects, we just treat it like a status with a subject; otherwise, we just treat it like a tall status. + mightHideBecauseSubject () { + return !!this.status.summary && this.localCollapseSubjectDefault + }, + mightHideBecauseTall () { + return this.tallStatus && !(this.status.summary && this.localCollapseSubjectDefault) + }, + hideSubjectStatus () { + return this.mightHideBecauseSubject && !this.expandingSubject + }, + hideTallStatus () { + return this.mightHideBecauseTall && !this.showingTall + }, + showingMore () { + return (this.mightHideBecauseTall && this.showingTall) || (this.mightHideBecauseSubject && this.expandingSubject) + }, + postBodyHtml () { + const html = this.status.raw_html + + if (this.mergedConfig.greentext) { + try { + if (html.includes('>')) { + // This checks if post has '>' at the beginning, excluding mentions so that @mention >impying works + return processHtml(html, (string) => { + if (string.includes('>') && + string + .replace(/<[^>]+?>/gi, '') // remove all tags + .replace(/@\w+/gi, '') // remove mentions (even failed ones) + .trim() + .startsWith('>')) { + return `${string}` + } else { + return string + } + }) + } else { + return html + } + } catch (e) { + console.error('Failed to process status html', e) + return html + } + } else { + return html + } + }, + attachmentTypes () { + return this.status.attachments.map(file => fileType.fileType(file.mimetype)) + }, + ...mapGetters(['mergedConfig']) + }, + components: { + RichContent + }, + mounted () { + this.status.attentions && this.status.attentions.forEach(attn => { + const { id } = attn + this.$store.dispatch('fetchUserIfMissing', id) + }) + }, + methods: { + linkClicked (event) { + const target = event.target.closest('.status-content a') + if (target) { + if (target.rel.match(/(?:^|\s)tag(?:$|\s)/) || target.className.match(/hashtag/)) { + // Extract tag name from dataset or link url + const tag = target.dataset.tag || extractTagFromUrl(target.href) + if (tag) { + const link = this.generateTagLink(tag) + this.$router.push(link) + return + } + } + window.open(target.href, '_blank') + } + }, + toggleShowMore () { + if (this.mightHideBecauseTall) { + this.showingTall = !this.showingTall + } else if (this.mightHideBecauseSubject) { + this.expandingSubject = !this.expandingSubject + } + }, + generateTagLink (tag) { + return `/tag/${tag}` + } + } +} + +export default StatusContent diff --git a/src/components/status_body/status_body.scss b/src/components/status_body/status_body.scss new file mode 100644 index 00000000..6282919c --- /dev/null +++ b/src/components/status_body/status_body.scss @@ -0,0 +1,112 @@ +@import '../../_variables.scss'; + +.StatusBody { + .emoji { + --_still_image-label-scale: 0.5; + } + + .summary { + display: block; + font-style: italic; + padding-bottom: 0.5em; + } + + .text { + &.-single-line { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + height: 1.4em; + } + } + + .summary-wrapper { + margin-bottom: 0.5em; + border-style: solid; + border-width: 0 0 1px 0; + border-color: var(--border, $fallback--border); + flex-grow: 0; + + &.-tall { + position: relative; + + .summary { + max-height: 2em; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + } + } + + .text-wrapper { + display: flex; + flex-direction: column; + flex-wrap: nowrap; + + &.-tall-status { + position: relative; + height: 220px; + overflow-x: hidden; + overflow-y: hidden; + z-index: 1; + + .text { + min-height: 0; + mask: + linear-gradient(to top, white, transparent) bottom/100% 70px no-repeat, + linear-gradient(to top, white, white); + + /* Autoprefixed seem to ignore this one, and also syntax is different */ + -webkit-mask-composite: xor; + mask-composite: exclude; + } + } + } + + & .tall-status-hider, + & .tall-subject-hider, + & .status-unhider, + & .cw-status-hider { + display: inline-block; + word-break: break-all; + width: 100%; + text-align: center; + } + + .tall-status-hider { + position: absolute; + height: 70px; + margin-top: 150px; + line-height: 110px; + z-index: 2; + } + + .tall-subject-hider { + // position: absolute; + padding-bottom: 0.5em; + } + + & .status-unhider, + & .cw-status-hider { + word-break: break-all; + + svg { + color: inherit; + } + } + + .greentext { + color: $fallback--cGreen; + color: var(--postGreentext, $fallback--cGreen); + } + + /* Not sure if this is necessary */ + video { + max-width: 100%; + max-height: 400px; + vertical-align: middle; + object-fit: contain; + } + +} diff --git a/src/components/status_body/status_body.vue b/src/components/status_body/status_body.vue new file mode 100644 index 00000000..6f982f2e --- /dev/null +++ b/src/components/status_body/status_body.vue @@ -0,0 +1,95 @@ + + + diff --git a/src/components/status_text/status_text.js b/src/components/status_text/status_text.js deleted file mode 100644 index e0b11edc..00000000 --- a/src/components/status_text/status_text.js +++ /dev/null @@ -1,147 +0,0 @@ -import fileType from 'src/services/file_type/file_type.service' -import RichContent from 'src/components/rich_content/rich_content.jsx' -import { processHtml } from 'src/services/tiny_post_html_processor/tiny_post_html_processor.service.js' -import { extractTagFromUrl } from 'src/services/matcher/matcher.service.js' -import { mapGetters } from 'vuex' -import { library } from '@fortawesome/fontawesome-svg-core' -import { - faFile, - faMusic, - faImage, - faLink, - faPollH -} from '@fortawesome/free-solid-svg-icons' - -library.add( - faFile, - faMusic, - faImage, - faLink, - faPollH -) - -const StatusContent = { - name: 'StatusContent', - props: [ - 'status', - 'focused', - 'noHeading', - 'fullContent', - 'singleLine' - ], - data () { - return { - showingTall: this.fullContent || (this.inConversation && this.focused), - showingLongSubject: false, - // not as computed because it sets the initial state which will be changed later - expandingSubject: !this.$store.getters.mergedConfig.collapseMessageWithSubject - } - }, - computed: { - localCollapseSubjectDefault () { - return this.mergedConfig.collapseMessageWithSubject - }, - // This is a bit hacky, but we want to approximate post height before rendering - // so we count newlines (masto uses

for paragraphs, GS uses
between them) - // as well as approximate line count by counting characters and approximating ~80 - // per line. - // - // Using max-height + overflow: auto for status components resulted in false positives - // very often with japanese characters, and it was very annoying. - tallStatus () { - const lengthScore = this.status.statusnet_html.split(/ 20 - }, - longSubject () { - return this.status.summary.length > 240 - }, - // When a status has a subject and is also tall, we should only have one show more/less button. If the default is to collapse statuses with subjects, we just treat it like a status with a subject; otherwise, we just treat it like a tall status. - mightHideBecauseSubject () { - return !!this.status.summary && this.localCollapseSubjectDefault - }, - mightHideBecauseTall () { - return this.tallStatus && !(this.status.summary && this.localCollapseSubjectDefault) - }, - hideSubjectStatus () { - return this.mightHideBecauseSubject && !this.expandingSubject - }, - hideTallStatus () { - return this.mightHideBecauseTall && !this.showingTall - }, - showingMore () { - return (this.mightHideBecauseTall && this.showingTall) || (this.mightHideBecauseSubject && this.expandingSubject) - }, - postBodyHtml () { - const html = this.status.raw_html - - if (this.mergedConfig.greentext) { - try { - if (html.includes('>')) { - // This checks if post has '>' at the beginning, excluding mentions so that @mention >impying works - return processHtml(html, (string) => { - if (string.includes('>') && - string - .replace(/<[^>]+?>/gi, '') // remove all tags - .replace(/@\w+/gi, '') // remove mentions (even failed ones) - .trim() - .startsWith('>')) { - return `${string}` - } else { - return string - } - }) - } else { - return html - } - } catch (e) { - console.err('Failed to process status html', e) - return html - } - } else { - return html - } - }, - attachmentTypes () { - return this.status.attachments.map(file => fileType.fileType(file.mimetype)) - }, - ...mapGetters(['mergedConfig']), - }, - components: { - RichContent - }, - mounted () { - this.status.attentions.forEach(attn => { - const { id } = attn - this.$store.dispatch('fetchUserIfMissing', id) - }) - }, - methods: { - linkClicked (event) { - const target = event.target.closest('.status-content a') - if (target) { - if (target.rel.match(/(?:^|\s)tag(?:$|\s)/) || target.className.match(/hashtag/)) { - // Extract tag name from dataset or link url - const tag = target.dataset.tag || extractTagFromUrl(target.href) - if (tag) { - const link = this.generateTagLink(tag) - this.$router.push(link) - return - } - } - window.open(target.href, '_blank') - } - }, - toggleShowMore () { - if (this.mightHideBecauseTall) { - this.showingTall = !this.showingTall - } else if (this.mightHideBecauseSubject) { - this.expandingSubject = !this.expandingSubject - } - }, - generateTagLink (tag) { - return `/tag/${tag}` - } - } -} - -export default StatusContent diff --git a/src/components/status_text/status_text.vue b/src/components/status_text/status_text.vue deleted file mode 100644 index bf723e15..00000000 --- a/src/components/status_text/status_text.vue +++ /dev/null @@ -1,95 +0,0 @@ - - diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index 8dc22823..13162dcf 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -448,6 +448,8 @@ export const parseChatMessage = (message) => { output.id = message.id output.created_at = new Date(message.created_at) output.chat_id = message.chat_id + output.emojis = message.emojis + output.content_raw = message.content if (message.content) { output.content = addEmojis(message.content, message.emojis) } else { diff --git a/src/services/mini_html_converter/mini_html_converter.service.js b/src/services/mini_html_converter/mini_html_converter.service.js index 01f8adf8..900752cd 100644 --- a/src/services/mini_html_converter/mini_html_converter.service.js +++ b/src/services/mini_html_converter/mini_html_converter.service.js @@ -1,6 +1,6 @@ /** * This is a not-so-tiny purpose-built HTML parser/processor. It was made for use - * with StatusText component for purpose of replacing tags with vue components + * with StatusBody component for purpose of replacing tags with vue components * * known issue: doesn't handle CDATA so nested CDATA might not work well * diff --git a/yarn.lock b/yarn.lock index 23cc895b..9329cc3a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1011,23 +1011,86 @@ resolved "https://registry.yarnpkg.com/@ungap/event-target/-/event-target-0.1.0.tgz#88d527d40de86c4b0c99a060ca241d755999915b" integrity sha512-W2oyj0Fe1w/XhPZjkI3oUcDUAmu5P4qsdT2/2S8aMhtAWM/CE/jYWtji0pKNPDfxLI75fa5gWSEmnynKMNP/oA== -"@vue/babel-helper-vue-jsx-merge-props@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.0.0.tgz#048fe579958da408fb7a8b2a3ec050b50a661040" - integrity sha512-6tyf5Cqm4m6v7buITuwS+jHzPlIPxbFzEhXR5JGZpbrvOcp1hiQKckd305/3C7C36wFekNTQSxAtgeM0j0yoUw== +"@vue/babel-helper-vue-jsx-merge-props@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.2.1.tgz#31624a7a505fb14da1d58023725a4c5f270e6a81" + integrity sha512-QOi5OW45e2R20VygMSNhyQHvpdUwQZqGPc748JLGCYEy+yp8fNFNdbNIGAgZmi9e+2JHPd6i6idRuqivyicIkA== -"@vue/babel-plugin-transform-vue-jsx@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.1.2.tgz#c0a3e6efc022e75e4247b448a8fc6b86f03e91c0" - integrity sha512-YfdaoSMvD1nj7+DsrwfTvTnhDXI7bsuh+Y5qWwvQXlD24uLgnsoww3qbiZvWf/EoviZMrvqkqN4CBw0W3BWUTQ== +"@vue/babel-plugin-transform-vue-jsx@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.2.1.tgz#646046c652c2f0242727f34519d917b064041ed7" + integrity sha512-HJuqwACYehQwh1fNT8f4kyzqlNMpBuUK4rSiSES5D4QsYncv5fxFsLyrxFPG2ksO7t5WP+Vgix6tt6yKClwPzA== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/plugin-syntax-jsx" "^7.2.0" - "@vue/babel-helper-vue-jsx-merge-props" "^1.0.0" + "@vue/babel-helper-vue-jsx-merge-props" "^1.2.1" html-tags "^2.0.0" lodash.kebabcase "^4.1.1" svg-tags "^1.0.0" +"@vue/babel-preset-jsx@^1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@vue/babel-preset-jsx/-/babel-preset-jsx-1.2.4.tgz#92fea79db6f13b01e80d3a0099e2924bdcbe4e87" + integrity sha512-oRVnmN2a77bYDJzeGSt92AuHXbkIxbf/XXSE3klINnh9AXBmVS1DGa1f0d+dDYpLfsAKElMnqKTQfKn7obcL4w== + dependencies: + "@vue/babel-helper-vue-jsx-merge-props" "^1.2.1" + "@vue/babel-plugin-transform-vue-jsx" "^1.2.1" + "@vue/babel-sugar-composition-api-inject-h" "^1.2.1" + "@vue/babel-sugar-composition-api-render-instance" "^1.2.4" + "@vue/babel-sugar-functional-vue" "^1.2.2" + "@vue/babel-sugar-inject-h" "^1.2.2" + "@vue/babel-sugar-v-model" "^1.2.3" + "@vue/babel-sugar-v-on" "^1.2.3" + +"@vue/babel-sugar-composition-api-inject-h@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-composition-api-inject-h/-/babel-sugar-composition-api-inject-h-1.2.1.tgz#05d6e0c432710e37582b2be9a6049b689b6f03eb" + integrity sha512-4B3L5Z2G+7s+9Bwbf+zPIifkFNcKth7fQwekVbnOA3cr3Pq71q71goWr97sk4/yyzH8phfe5ODVzEjX7HU7ItQ== + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + +"@vue/babel-sugar-composition-api-render-instance@^1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-composition-api-render-instance/-/babel-sugar-composition-api-render-instance-1.2.4.tgz#e4cbc6997c344fac271785ad7a29325c51d68d19" + integrity sha512-joha4PZznQMsxQYXtR3MnTgCASC9u3zt9KfBxIeuI5g2gscpTsSKRDzWQt4aqNIpx6cv8On7/m6zmmovlNsG7Q== + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + +"@vue/babel-sugar-functional-vue@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.2.2.tgz#267a9ac8d787c96edbf03ce3f392c49da9bd2658" + integrity sha512-JvbgGn1bjCLByIAU1VOoepHQ1vFsroSA/QkzdiSs657V79q6OwEWLCQtQnEXD/rLTA8rRit4rMOhFpbjRFm82w== + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + +"@vue/babel-sugar-inject-h@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.2.2.tgz#d738d3c893367ec8491dcbb669b000919293e3aa" + integrity sha512-y8vTo00oRkzQTgufeotjCLPAvlhnpSkcHFEp60+LJUwygGcd5Chrpn5480AQp/thrxVm8m2ifAk0LyFel9oCnw== + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + +"@vue/babel-sugar-v-model@^1.2.3": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.2.3.tgz#fa1f29ba51ebf0aa1a6c35fa66d539bc459a18f2" + integrity sha512-A2jxx87mySr/ulAsSSyYE8un6SIH0NWHiLaCWpodPCVOlQVODCaSpiR4+IMsmBr73haG+oeCuSvMOM+ttWUqRQ== + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + "@vue/babel-helper-vue-jsx-merge-props" "^1.2.1" + "@vue/babel-plugin-transform-vue-jsx" "^1.2.1" + camelcase "^5.0.0" + html-tags "^2.0.0" + svg-tags "^1.0.0" + +"@vue/babel-sugar-v-on@^1.2.3": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.2.3.tgz#342367178586a69f392f04bfba32021d02913ada" + integrity sha512-kt12VJdz/37D3N3eglBywV8GStKNUhNrsxChXIV+o0MwVXORYuhDTHJRKPgLJRb/EY3vM2aRFQdxJBp9CLikjw== + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + "@vue/babel-plugin-transform-vue-jsx" "^1.2.1" + camelcase "^5.0.0" + "@vue/test-utils@^1.0.0-beta.26": version "1.0.0-beta.28" resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-1.0.0-beta.28.tgz#767c43413df8cde86128735e58923803e444b9a5" -- cgit v1.2.3-70-g09d2 From 90a188f2c3c16b926c75bf4aa749633e6967e5a0 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Sat, 12 Jun 2021 19:54:03 +0300 Subject: cleanup --- src/components/chat_list_item/chat_list_item.js | 3 +-- src/components/chat_message/chat_message.js | 3 +-- src/components/status_body/status_body.js | 2 +- src/services/entity_normalizer/entity_normalizer.service.js | 5 ++--- .../specs/services/entity_normalizer/entity_normalizer.spec.js | 9 --------- 5 files changed, 5 insertions(+), 17 deletions(-) (limited to 'src/services/entity_normalizer/entity_normalizer.service.js') diff --git a/src/components/chat_list_item/chat_list_item.js b/src/components/chat_list_item/chat_list_item.js index e01b9bd4..e5032176 100644 --- a/src/components/chat_list_item/chat_list_item.js +++ b/src/components/chat_list_item/chat_list_item.js @@ -40,12 +40,11 @@ const ChatListItem = { const message = this.chat.lastMessage const messageEmojis = message ? message.emojis : [] const isYou = message && message.account_id === this.currentUser.id - const content = message ? (this.attachmentInfo || message.content_raw) : '' + const content = message ? (this.attachmentInfo || message.content) : '' const messagePreview = isYou ? `${this.$t('chats.you')} ${content}` : content return { summary: '', emojis: messageEmojis, - statusnet_html: messagePreview, raw_html: messagePreview, text: messagePreview, attachments: [] diff --git a/src/components/chat_message/chat_message.js b/src/components/chat_message/chat_message.js index d126d453..9a2d1e7d 100644 --- a/src/components/chat_message/chat_message.js +++ b/src/components/chat_message/chat_message.js @@ -58,8 +58,7 @@ const ChatMessage = { return { summary: '', emojis: this.message.emojis, - raw_html: this.message.content_raw, - statusnet_html: this.message.content, + raw_html: this.message.content, text: this.message.content, attachments: this.message.attachments } diff --git a/src/components/status_body/status_body.js b/src/components/status_body/status_body.js index 14558aca..26491e1b 100644 --- a/src/components/status_body/status_body.js +++ b/src/components/status_body/status_body.js @@ -53,7 +53,7 @@ const StatusContent = { // Using max-height + overflow: auto for status components resulted in false positives // very often with japanese characters, and it was very annoying. tallStatus () { - const lengthScore = this.status.statusnet_html.split(/ 20 }, longSubject () { diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index 13162dcf..613ed566 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -267,7 +267,6 @@ export const parseStatus = (data) => { output.type = data.reblog ? 'retweet' : 'status' output.nsfw = data.sensitive - output.statusnet_html = addEmojis(data.content, data.emojis) output.raw_html = data.content output.emojis = data.emojis @@ -329,7 +328,7 @@ export const parseStatus = (data) => { output.nsfw = data.nsfw } - output.statusnet_html = data.statusnet_html + output.raw_html = data.statusnet_html output.text = data.text output.in_reply_to_status_id = data.in_reply_to_status_id @@ -449,7 +448,7 @@ export const parseChatMessage = (message) => { output.created_at = new Date(message.created_at) output.chat_id = message.chat_id output.emojis = message.emojis - output.content_raw = message.content + output.content = message.content if (message.content) { output.content = addEmojis(message.content, message.emojis) } else { 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 759539e0..c8965785 100644 --- a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js +++ b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js @@ -23,7 +23,6 @@ const makeMockStatusQvitter = (overrides = {}) => { repeat_num: 0, repeated: false, statusnet_conversation_id: '16300488', - statusnet_html: '

haha benis

', summary: null, tags: [], text: 'haha benis', @@ -233,14 +232,6 @@ describe('API Entities normalizer', () => { expect(parsedRepeat).to.have.deep.property('retweeted_status.id', 'deadbeef') }) - it('adds emojis to post content', () => { - const post = makeMockStatusMasto({ emojis: makeMockEmojiMasto(), content: 'Makes you think :thinking:' }) - - const parsedPost = parseStatus(post) - - expect(parsedPost).to.have.property('statusnet_html').that.contains(' { const post = makeMockStatusMasto({ emojis: makeMockEmojiMasto(), spoiler_text: 'CW: 300 IQ :thinking:' }) -- cgit v1.2.3-70-g09d2 From 418f029789f5e1cc22fd7db4f269088633d90050 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Sat, 12 Jun 2021 20:42:17 +0300 Subject: review + fixes --- src/components/mention_link/mention_link.vue | 2 -- src/components/mentions_line/mentions_line.scss | 1 + src/components/rich_content/rich_content.jsx | 21 ++++++++++++++++ .../settings_modal/tabs/theme_tab/theme_tab.js | 2 +- src/components/status/status.js | 6 ++--- src/components/status_body/status_body.scss | 8 ------- src/components/status_body/status_body.vue | 4 ++-- .../entity_normalizer/entity_normalizer.service.js | 6 ----- test/unit/specs/components/rich_content.spec.js | 28 ++++++++++++++++++++++ .../entity_normalizer/entity_normalizer.spec.js | 8 ------- 10 files changed, 55 insertions(+), 31 deletions(-) (limited to 'src/services/entity_normalizer/entity_normalizer.service.js') diff --git a/src/components/mention_link/mention_link.vue b/src/components/mention_link/mention_link.vue index 3449f4bd..e4d395fa 100644 --- a/src/components/mention_link/mention_link.vue +++ b/src/components/mention_link/mention_link.vue @@ -41,12 +41,10 @@ class="full popover-default" :class="[highlightType]" > - - diff --git a/src/components/mentions_line/mentions_line.scss b/src/components/mentions_line/mentions_line.scss index 59f75fbb..90d1e0a4 100644 --- a/src/components/mentions_line/mentions_line.scss +++ b/src/components/mentions_line/mentions_line.scss @@ -1,6 +1,7 @@ .MentionsLine { .showMoreLess { white-space: normal; + &.-newStyle { line-height: 1.5; font-size: inherit; diff --git a/src/components/rich_content/rich_content.jsx b/src/components/rich_content/rich_content.jsx index ef15aaeb..0aae7a55 100644 --- a/src/components/rich_content/rich_content.jsx +++ b/src/components/rich_content/rich_content.jsx @@ -8,6 +8,25 @@ import MentionLink from 'src/components/mention_link/mention_link.vue' import './rich_content.scss' +/** + * RichContent, The Über-powered component for rendering Post HTML. + * + * This takes post HTML and does multiple things to it: + * - Converts mention links to -s + * - Removes mentions from beginning and end (hellthread style only) + * - Replaces emoji shortcodes with 'd images. + * + * Stuff like removing mentions from beginning and end is done so that they could + * be either replaced by collapsible or moved to separate place. + * There are two problems with this component's architecture: + * 1. Parsing HTML and rendering are inseparable. Attempts to separate the two + * proven to be a massive overcomplication due to amount of things done here. + * 2. We need to output both render and some extra data, which seems to be imp- + * possible in vue. Current solution is to emit 'parseReady' event when parsing + * is done within render() function. + * + * Apart from that one small hiccup with emit in render this _should_ be vue3-ready + */ export default Vue.component('RichContent', { name: 'RichContent', props: { @@ -241,8 +260,10 @@ export const preProcessPerLine = (html, greentext, handleLinks) => { .replace(/@\w+/gi, '') // remove mentions (even failed ones) .trim() if (cleanedString.startsWith('>')) { + nonEmptyIndex += 1 return `${string}` } else if (cleanedString.startsWith('<')) { + nonEmptyIndex += 1 return `${string}` } } diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.js b/src/components/settings_modal/tabs/theme_tab/theme_tab.js index 63416e93..85749045 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.js +++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.js @@ -474,7 +474,7 @@ export default { this.loadThemeFromLocalStorage(false, true) break case 'file': - console.error('Forcing snapshout from file is not supported yet') + console.error('Forcing snapshot from file is not supported yet') break } this.dismissWarning() diff --git a/src/components/status/status.js b/src/components/status/status.js index 5b178c2e..ae734493 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -35,8 +35,7 @@ import { faStar, faEyeSlash, faEye, - faThumbtack, - faAt + faThumbtack } from '@fortawesome/free-solid-svg-icons' library.add( @@ -53,8 +52,7 @@ library.add( faEllipsisH, faEyeSlash, faEye, - faThumbtack, - faAt + faThumbtack ) const Status = { diff --git a/src/components/status_body/status_body.scss b/src/components/status_body/status_body.scss index da5d4dd3..81a687f1 100644 --- a/src/components/status_body/status_body.scss +++ b/src/components/status_body/status_body.scss @@ -115,12 +115,4 @@ .cyantext { color: var(--postCyantext, $fallback--cBlue); } - - /* Not sure if this is necessary */ - video { - max-width: 100%; - max-height: 400px; - vertical-align: middle; - object-fit: contain; - } } diff --git a/src/components/status_body/status_body.vue b/src/components/status_body/status_body.vue index aac44e42..0eb11ad0 100644 --- a/src/components/status_body/status_body.vue +++ b/src/components/status_body/status_body.vue @@ -2,7 +2,7 @@
@@ -39,7 +39,7 @@ {{ $t("general.show_more") }} { } output.summary_raw_html = escape(data.spoiler_text) - output.summary_html = addEmojis(escape(data.spoiler_text), data.emojis) output.external_url = data.url output.poll = data.poll if (output.poll) { @@ -449,11 +448,6 @@ export const parseChatMessage = (message) => { output.chat_id = message.chat_id output.emojis = message.emojis output.content = message.content - if (message.content) { - output.content = addEmojis(message.content, message.emojis) - } else { - output.content = '' - } if (message.attachment) { output.attachments = [parseAttachment(message.attachment)] } else { diff --git a/test/unit/specs/components/rich_content.spec.js b/test/unit/specs/components/rich_content.spec.js index 05c0b259..f2c3f04e 100644 --- a/test/unit/specs/components/rich_content.spec.js +++ b/test/unit/specs/components/rich_content.spec.js @@ -354,4 +354,32 @@ describe('RichContent', () => { expect(wrapper.html()).to.eql(compwrap(html)) }) + + it('Greentext + last mentions', () => { + const html = [ + '>quote', + makeMention('lol'), + '>quote', + '>quote' + ].join('\n') + const expected = [ + '>quote', + stubMention('lol'), + '>quote', + '>quote' + ].join('\n') + + const wrapper = shallowMount(RichContent, { + localVue, + propsData: { + handleLinks: true, + greentext: true, + emoji: [], + html + } + }) + + expect(wrapper.html()).to.eql(compwrap(expected)) + }) + }) 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 c8965785..8a5a6ef9 100644 --- a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js +++ b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js @@ -231,14 +231,6 @@ describe('API Entities normalizer', () => { expect(parsedRepeat).to.have.property('retweeted_status') expect(parsedRepeat).to.have.deep.property('retweeted_status.id', 'deadbeef') }) - - it('adds emojis to subject line', () => { - const post = makeMockStatusMasto({ emojis: makeMockEmojiMasto(), spoiler_text: 'CW: 300 IQ :thinking:' }) - - const parsedPost = parseStatus(post) - - expect(parsedPost).to.have.property('summary_html').that.contains(' Date: Fri, 13 Aug 2021 12:19:57 +0300 Subject: support richcontent in polls --- src/components/poll/poll.js | 10 +++++++--- src/components/poll/poll.vue | 6 ++---- src/components/status_content/status_content.vue | 2 +- src/services/entity_normalizer/entity_normalizer.service.js | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) (limited to 'src/services/entity_normalizer/entity_normalizer.service.js') diff --git a/src/components/poll/poll.js b/src/components/poll/poll.js index 98db5582..a69b7886 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 187d1829..6e0234b3 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 23c90913..3f65e64a 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 -- cgit v1.2.3-70-g09d2 From 4c974f5ca21c6a514d0dfc09a0aeab7789da95c5 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Fri, 13 Aug 2021 13:06:42 +0300 Subject: richcontent support in polls, user cards and user profiles --- src/components/basic_user_card/basic_user_card.js | 4 +- src/components/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 ++--- src/components/notifications/notifications.scss | 7 --- src/components/poll/poll.vue | 12 ++++- src/components/rich_content/rich_content.scss | 1 + src/components/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/entity_normalizer.service.js | 5 +- 14 files changed, 69 insertions(+), 86 deletions(-) (limited to 'src/services/entity_normalizer/entity_normalizer.service.js') diff --git a/src/components/basic_user_card/basic_user_card.js b/src/components/basic_user_card/basic_user_card.js index 87085a28..8f41e2fb 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 c53f6a9c..53deb1df 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 12cb9776..db08ef1e 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 3f65e64a..5cebc697 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 c0b55a6c..7a475609 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 aef897ae..726216ff 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 => { -- cgit v1.2.3-70-g09d2 From 97e86381c868fbd49a33e190722934dee698600d Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Fri, 13 Aug 2021 13:12:33 +0300 Subject: remove old emoji added, everything emoji-bearing uses RichContent now --- .../entity_normalizer/entity_normalizer.service.js | 14 ++------ .../entity_normalizer/entity_normalizer.spec.js | 37 +--------------------- 2 files changed, 3 insertions(+), 48 deletions(-) (limited to 'src/services/entity_normalizer/entity_normalizer.service.js') diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index d84e3422..04bb45a4 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 8a5a6ef9..8932bc7c 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"' -- cgit v1.2.3-70-g09d2