feat: add preference to hide emojis in usernames (#1612)

This commit is contained in:
Tuur Martens 2023-02-04 18:02:05 +01:00 committed by GitHub
parent 0258894484
commit e92d1c6adf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 91 additions and 6 deletions

View file

@ -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)

View file

@ -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)))
}

View file

@ -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,