mirror of
https://github.com/elk-zone/elk.git
synced 2024-11-21 17:05:22 +03:00
feat: inline some mentions to reduce spacing (#1307)
This commit is contained in:
parent
1f427e2538
commit
a48524e7ad
2 changed files with 68 additions and 23 deletions
|
@ -469,6 +469,7 @@ function transformCollapseMentions(status?: mastodon.v1.Status, inReplyToStatus?
|
||||||
return node
|
return node
|
||||||
const mentions: (Node | undefined)[] = []
|
const mentions: (Node | undefined)[] = []
|
||||||
const children = node.children as Node[]
|
const children = node.children as Node[]
|
||||||
|
let trimContentStart: (() => void) | undefined
|
||||||
for (const child of children) {
|
for (const child of children) {
|
||||||
// mention
|
// mention
|
||||||
if (isMention(child)) {
|
if (isMention(child)) {
|
||||||
|
@ -480,8 +481,11 @@ function transformCollapseMentions(status?: mastodon.v1.Status, inReplyToStatus?
|
||||||
}
|
}
|
||||||
// other content, stop collapsing
|
// other content, stop collapsing
|
||||||
else {
|
else {
|
||||||
if (child.type === TEXT_NODE)
|
if (child.type === TEXT_NODE) {
|
||||||
child.value = child.value.trimStart()
|
trimContentStart = () => {
|
||||||
|
child.value = child.value.trimStart()
|
||||||
|
}
|
||||||
|
}
|
||||||
// remove <br> after mention
|
// remove <br> after mention
|
||||||
if (child.name === 'br')
|
if (child.name === 'br')
|
||||||
mentions.push(undefined)
|
mentions.push(undefined)
|
||||||
|
@ -495,6 +499,7 @@ function transformCollapseMentions(status?: mastodon.v1.Status, inReplyToStatus?
|
||||||
let mentionsCount = 0
|
let mentionsCount = 0
|
||||||
let contextualMentionsCount = 0
|
let contextualMentionsCount = 0
|
||||||
let removeNextSpacing = false
|
let removeNextSpacing = false
|
||||||
|
|
||||||
const contextualMentions = mentions.filter((mention) => {
|
const contextualMentions = mentions.filter((mention) => {
|
||||||
if (!mention)
|
if (!mention)
|
||||||
return false
|
return false
|
||||||
|
@ -508,24 +513,30 @@ function transformCollapseMentions(status?: mastodon.v1.Status, inReplyToStatus?
|
||||||
mentionsCount++
|
mentionsCount++
|
||||||
if (inReplyToStatus) {
|
if (inReplyToStatus) {
|
||||||
const mentionHandle = getMentionHandle(mention)
|
const mentionHandle = getMentionHandle(mention)
|
||||||
if (inReplyToStatus.account.acct === mentionHandle || inReplyToStatus.mentions.some(m => m.acct === mentionHandle))
|
if (inReplyToStatus.account.acct === mentionHandle || inReplyToStatus.mentions.some(m => m.acct === mentionHandle)) {
|
||||||
|
removeNextSpacing = true
|
||||||
return false
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
contextualMentionsCount++
|
contextualMentionsCount++
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
})
|
}) as Node[]
|
||||||
|
|
||||||
// We have a special case for single mentions that are part of a reply.
|
// We have a special case for single mentions that are part of a reply.
|
||||||
// We already have the replying to badge in this case or the status is connected to the previous one.
|
// We already have the replying to badge in this case or the status is connected to the previous one.
|
||||||
// This is needed because the status doesn't included the in Reply to handle, only the account id.
|
// This is needed because the status doesn't included the in Reply to handle, only the account id.
|
||||||
// But this covers the majority of cases.
|
// But this covers the majority of cases.
|
||||||
const showMentions = !(contextualMentionsCount === 0 || (mentionsCount === 1 && status?.inReplyToAccountId))
|
const showMentions = !(contextualMentionsCount === 0 || (mentionsCount === 1 && status?.inReplyToAccountId))
|
||||||
|
const grouped = contextualMentionsCount > 2
|
||||||
|
if (grouped)
|
||||||
|
trimContentStart?.()
|
||||||
|
|
||||||
const contextualChildren = children.slice(mentions.length)
|
const contextualChildren = children.slice(mentions.length)
|
||||||
|
const mentionNodes = showMentions ? (grouped ? [h('mention-group', null, ...contextualMentions)] : contextualMentions) : []
|
||||||
return {
|
return {
|
||||||
...node,
|
...node,
|
||||||
children: showMentions ? [h('mention-group', null, ...contextualMentions), ...contextualChildren] : contextualChildren,
|
children: [...mentionNodes, ...contextualChildren],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,21 +91,21 @@ describe('content-rich', () => {
|
||||||
})
|
})
|
||||||
expect(formatted).toMatchInlineSnapshot(`
|
expect(formatted).toMatchInlineSnapshot(`
|
||||||
"<p>
|
"<p>
|
||||||
<mention-group
|
<span class=\\"h-card\\"
|
||||||
><span class=\\"h-card\\"
|
><a
|
||||||
><a
|
class=\\"u-url mention\\"
|
||||||
class=\\"u-url mention\\"
|
rel=\\"nofollow noopener noreferrer\\"
|
||||||
rel=\\"nofollow noopener noreferrer\\"
|
to=\\"/m.webtoo.ls/@elk\\"
|
||||||
to=\\"/m.webtoo.ls/@elk\\"
|
></a
|
||||||
></a
|
></span>
|
||||||
></span>
|
<span class=\\"h-card\\"
|
||||||
<span class=\\"h-card\\"
|
><a
|
||||||
><a
|
class=\\"u-url mention\\"
|
||||||
class=\\"u-url mention\\"
|
rel=\\"nofollow noopener noreferrer\\"
|
||||||
rel=\\"nofollow noopener noreferrer\\"
|
to=\\"/m.webtoo.ls/@elk\\"
|
||||||
to=\\"/m.webtoo.ls/@elk\\"
|
></a
|
||||||
></a></span></mention-group
|
></span>
|
||||||
>content
|
content
|
||||||
<span class=\\"h-card\\"
|
<span class=\\"h-card\\"
|
||||||
><a
|
><a
|
||||||
class=\\"u-url mention\\"
|
class=\\"u-url mention\\"
|
||||||
|
@ -151,19 +151,53 @@ describe('content-rich', () => {
|
||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('shows some collapsed mentions', async () => {
|
it('shows some collapsed mentions inline', async () => {
|
||||||
const { formatted } = await render('<p><span class="h-card"><a href="https://m.webtoo.ls/@elk" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>elk</span></a></span> <span class="h-card"><a href="https://m.webtoo.ls/@antfu" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>antfu</span></a></span> content</p>', {
|
const { formatted } = await render('<p><span class="h-card"><a href="https://m.webtoo.ls/@elk" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>elk</span></a></span> <span class="h-card"><a href="https://m.webtoo.ls/@antfu" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>antfu</span></a></span> content</p>', {
|
||||||
collapseMentionLink: true,
|
collapseMentionLink: true,
|
||||||
inReplyToStatus: { account: { acct: 'elk@webtoo.ls' }, mentions: [] as mastodon.v1.StatusMention[] } as mastodon.v1.Status,
|
inReplyToStatus: { account: { acct: 'elk@webtoo.ls' }, mentions: [] as mastodon.v1.StatusMention[] } as mastodon.v1.Status,
|
||||||
})
|
})
|
||||||
expect(formatted).toMatchInlineSnapshot(`
|
expect(formatted).toMatchInlineSnapshot(`
|
||||||
"<p>
|
"<p>
|
||||||
<mention-group>
|
<span class=\\"h-card\\"
|
||||||
<span class=\\"h-card\\"
|
><a
|
||||||
|
class=\\"u-url mention\\"
|
||||||
|
rel=\\"nofollow noopener noreferrer\\"
|
||||||
|
to=\\"/m.webtoo.ls/@antfu\\"
|
||||||
|
></a
|
||||||
|
></span>
|
||||||
|
content
|
||||||
|
</p>
|
||||||
|
"
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shows some collapsed mentions grouped', async () => {
|
||||||
|
const { formatted } = await render('<p><span class="h-card"><a href="https://m.webtoo.ls/@elk" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>elk</span></a></span> <span class="h-card"><a href="https://m.webtoo.ls/@antfu" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>antfu</span></a></span> <span class="h-card"><a href="https://m.webtoo.ls/@patak" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>patak</span></a></span> <span class="h-card"><a href="https://m.webtoo.ls/@sxzz" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>sxzz</span></a></span>content</p>', {
|
||||||
|
collapseMentionLink: true,
|
||||||
|
inReplyToStatus: { account: { acct: 'elk@webtoo.ls' }, mentions: [] as mastodon.v1.StatusMention[] } as mastodon.v1.Status,
|
||||||
|
})
|
||||||
|
expect(formatted).toMatchInlineSnapshot(`
|
||||||
|
"<p>
|
||||||
|
<mention-group
|
||||||
|
><span class=\\"h-card\\"
|
||||||
><a
|
><a
|
||||||
class=\\"u-url mention\\"
|
class=\\"u-url mention\\"
|
||||||
rel=\\"nofollow noopener noreferrer\\"
|
rel=\\"nofollow noopener noreferrer\\"
|
||||||
to=\\"/m.webtoo.ls/@antfu\\"
|
to=\\"/m.webtoo.ls/@antfu\\"
|
||||||
|
></a
|
||||||
|
></span>
|
||||||
|
<span class=\\"h-card\\"
|
||||||
|
><a
|
||||||
|
class=\\"u-url mention\\"
|
||||||
|
rel=\\"nofollow noopener noreferrer\\"
|
||||||
|
to=\\"/m.webtoo.ls/@patak\\"
|
||||||
|
></a
|
||||||
|
></span>
|
||||||
|
<span class=\\"h-card\\"
|
||||||
|
><a
|
||||||
|
class=\\"u-url mention\\"
|
||||||
|
rel=\\"nofollow noopener noreferrer\\"
|
||||||
|
to=\\"/m.webtoo.ls/@sxzz\\"
|
||||||
></a></span></mention-group
|
></a></span></mention-group
|
||||||
>content
|
>content
|
||||||
</p>
|
</p>
|
||||||
|
|
Loading…
Reference in a new issue