feat: add preference to hide emojis in usernames (#1612)
This commit is contained in:
parent
0258894484
commit
e92d1c6adf
8 changed files with 91 additions and 6 deletions
|
@ -8,6 +8,7 @@ import { emojiRegEx, getEmojiAttributes } from '../config/emojis'
|
|||
|
||||
export interface ContentParseOptions {
|
||||
emojis?: Record<string, mastodon.v1.CustomEmoji>
|
||||
showEmojis?: boolean
|
||||
mentions?: mastodon.v1.StatusMention[]
|
||||
markdown?: boolean
|
||||
replaceUnicodeEmoji?: boolean
|
||||
|
@ -81,6 +82,7 @@ export function parseMastodonHTML(
|
|||
replaceUnicodeEmoji = true,
|
||||
convertMentionLink = false,
|
||||
collapseMentionLink = false,
|
||||
showEmojis = true,
|
||||
mentions,
|
||||
status,
|
||||
inReplyToStatus,
|
||||
|
@ -108,8 +110,16 @@ export function parseMastodonHTML(
|
|||
...options.astTransforms || [],
|
||||
]
|
||||
|
||||
if (replaceUnicodeEmoji)
|
||||
transforms.push(transformUnicodeEmoji)
|
||||
if (showEmojis) {
|
||||
if (replaceUnicodeEmoji)
|
||||
transforms.push(transformUnicodeEmoji)
|
||||
|
||||
transforms.push(replaceCustomEmoji(options.emojis ?? {}))
|
||||
}
|
||||
else {
|
||||
transforms.push(removeUnicodeEmoji)
|
||||
transforms.push(removeCustomEmoji(options.emojis ?? {}))
|
||||
}
|
||||
|
||||
if (markdown)
|
||||
transforms.push(transformMarkdown)
|
||||
|
@ -120,8 +130,6 @@ export function parseMastodonHTML(
|
|||
if (convertMentionLink)
|
||||
transforms.push(transformMentionLink)
|
||||
|
||||
transforms.push(replaceCustomEmoji(options.emojis || {}))
|
||||
|
||||
transforms.push(transformParagraphs)
|
||||
|
||||
if (collapseMentionLink)
|
||||
|
@ -329,6 +337,25 @@ function filterHref() {
|
|||
}
|
||||
}
|
||||
|
||||
function removeUnicodeEmoji(node: Node) {
|
||||
if (node.type !== TEXT_NODE)
|
||||
return node
|
||||
|
||||
let start = 0
|
||||
|
||||
const matches = [] as (string | Node)[]
|
||||
findAndReplaceEmojisInText(emojiRegEx, node.value, (match, result) => {
|
||||
matches.push(result.slice(start).trimEnd())
|
||||
start = result.length + match.match.length
|
||||
return undefined
|
||||
})
|
||||
if (matches.length === 0)
|
||||
return node
|
||||
|
||||
matches.push(node.value.slice(start))
|
||||
return matches.filter(Boolean)
|
||||
}
|
||||
|
||||
function transformUnicodeEmoji(node: Node) {
|
||||
if (node.type !== TEXT_NODE)
|
||||
return node
|
||||
|
@ -350,6 +377,28 @@ function transformUnicodeEmoji(node: Node) {
|
|||
return matches.filter(Boolean)
|
||||
}
|
||||
|
||||
function removeCustomEmoji(customEmojis: Record<string, mastodon.v1.CustomEmoji>): Transform {
|
||||
return (node) => {
|
||||
if (node.type !== TEXT_NODE)
|
||||
return node
|
||||
|
||||
const split = node.value.split(/\s?:([\w-]+?):/g)
|
||||
if (split.length === 1)
|
||||
return node
|
||||
|
||||
return split.map((name, i) => {
|
||||
if (i % 2 === 0)
|
||||
return name
|
||||
|
||||
const emoji = customEmojis[name] as mastodon.v1.CustomEmoji
|
||||
if (!emoji)
|
||||
return `:${name}:`
|
||||
|
||||
return ''
|
||||
}).filter(Boolean)
|
||||
}
|
||||
}
|
||||
|
||||
function replaceCustomEmoji(customEmojis: Record<string, mastodon.v1.CustomEmoji>): Transform {
|
||||
return (node) => {
|
||||
if (node.type !== TEXT_NODE)
|
||||
|
|
|
@ -10,6 +10,14 @@ import ContentCode from '~/components/content/ContentCode.vue'
|
|||
import ContentMentionGroup from '~/components/content/ContentMentionGroup.vue'
|
||||
import AccountHoverWrapper from '~/components/account/AccountHoverWrapper.vue'
|
||||
|
||||
function getTexualAstComponents(astChildren: Node[]): string {
|
||||
return astChildren
|
||||
.filter(({ type }) => type === TEXT_NODE)
|
||||
.map(({ value }) => value)
|
||||
.reduce((accumulator, current) => accumulator + current, '')
|
||||
.trim()
|
||||
}
|
||||
|
||||
/**
|
||||
* Raw HTML to VNodes
|
||||
*/
|
||||
|
@ -17,7 +25,14 @@ export function contentToVNode(
|
|||
content: string,
|
||||
options?: ContentParseOptions,
|
||||
): VNode {
|
||||
const tree = parseMastodonHTML(content, options)
|
||||
let tree = parseMastodonHTML(content, options)
|
||||
|
||||
const textContents = getTexualAstComponents(tree.children)
|
||||
|
||||
// if the username only contains emojis, we should probably show the emojis anyway to avoid a blank name
|
||||
if (!options?.showEmojis && textContents.length === 0)
|
||||
tree = parseMastodonHTML(content, { ...options, showEmojis: true })
|
||||
|
||||
return h(Fragment, (tree.children as Node[] || []).map(n => treeToVNode(n)))
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ export interface PreferencesSettings {
|
|||
hideFavoriteCount: boolean
|
||||
hideFollowerCount: boolean
|
||||
hideTranslation: boolean
|
||||
hideUsernameEmojis: boolean
|
||||
hideAccountHoverCard: boolean
|
||||
grayscaleMode: boolean
|
||||
enableAutoplay: boolean
|
||||
|
@ -72,6 +73,7 @@ export const DEFAULT__PREFERENCES_SETTINGS: PreferencesSettings = {
|
|||
hideFavoriteCount: false,
|
||||
hideFollowerCount: false,
|
||||
hideTranslation: false,
|
||||
hideUsernameEmojis: false,
|
||||
hideAccountHoverCard: false,
|
||||
grayscaleMode: false,
|
||||
enableAutoplay: true,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue