mirror of
https://git.shipoclu.com/moon/plspace.git
synced 2026-08-13 02:42:30 +00:00
refactor and fix all references to emojis
This commit is contained in:
@@ -6,14 +6,16 @@
|
||||
* when it's revealed, and the reveal is per-attachment because a single post
|
||||
* can mix flagged and unflagged media.
|
||||
*/
|
||||
import type { MediaAttachment } from '$lib/api/types'
|
||||
import type { CustomEmoji, MediaAttachment } from '$lib/api/types'
|
||||
import EmojiText from '../common/EmojiText.svelte'
|
||||
|
||||
interface Props {
|
||||
attachments: MediaAttachment[]
|
||||
emojis?: CustomEmoji[]
|
||||
sensitive?: boolean
|
||||
}
|
||||
|
||||
let { attachments, sensitive = false }: Props = $props()
|
||||
let { attachments, emojis, sensitive = false }: Props = $props()
|
||||
|
||||
let revealed = $state<Record<string, boolean>>({})
|
||||
|
||||
@@ -81,7 +83,9 @@
|
||||
{/if}
|
||||
|
||||
{#if media.description}
|
||||
<figcaption class="attachment-caption">{media.description}</figcaption>
|
||||
<figcaption class="attachment-caption">
|
||||
<EmojiText text={media.description} {emojis} />
|
||||
</figcaption>
|
||||
{/if}
|
||||
</figure>
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
import { isoDate, longDate, stampDate } from '$lib/util/time'
|
||||
import { extractYouTubeVideoIds } from '$lib/util/youtube'
|
||||
import Avatar from '../common/Avatar.svelte'
|
||||
import EmojiText from '../common/EmojiText.svelte'
|
||||
import MfmContent from '../common/MfmContent.svelte'
|
||||
import Attachments from './Attachments.svelte'
|
||||
import EmojiReactions from './EmojiReactions.svelte'
|
||||
@@ -145,7 +146,10 @@
|
||||
>
|
||||
{#if booster}
|
||||
<p class="blog-entry-attribution">
|
||||
<a href={profilePath(booster)}>{displayNameOf(booster)}</a> reposted this
|
||||
<a href={profilePath(booster)}>
|
||||
<EmojiText text={displayNameOf(booster)} emojis={booster.emojis} />
|
||||
</a>
|
||||
reposted this
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
@@ -181,7 +185,9 @@
|
||||
<div class="blog-entry-body">
|
||||
{#if entry.spoiler_text}
|
||||
<details class="content-warning">
|
||||
<summary class="content-warning-summary">{entry.spoiler_text}</summary>
|
||||
<summary class="content-warning-summary">
|
||||
<EmojiText text={entry.spoiler_text} emojis={entry.emojis} />
|
||||
</summary>
|
||||
<MfmContent
|
||||
html={entry.content}
|
||||
emojis={entry.emojis}
|
||||
@@ -190,7 +196,7 @@
|
||||
lang={entry.language}
|
||||
/>
|
||||
{#if entry.media_attachments.length > 0}
|
||||
<Attachments attachments={entry.media_attachments} sensitive={entry.sensitive} />
|
||||
<Attachments attachments={entry.media_attachments} emojis={entry.emojis} sensitive={entry.sensitive} />
|
||||
{/if}
|
||||
<YouTubeEmbeds videoIds={youtubeVideoIds} sensitive={entry.sensitive} />
|
||||
</details>
|
||||
@@ -203,7 +209,7 @@
|
||||
lang={entry.language}
|
||||
/>
|
||||
{#if entry.media_attachments.length > 0}
|
||||
<Attachments attachments={entry.media_attachments} sensitive={entry.sensitive} />
|
||||
<Attachments attachments={entry.media_attachments} emojis={entry.emojis} sensitive={entry.sensitive} />
|
||||
{/if}
|
||||
<YouTubeEmbeds videoIds={youtubeVideoIds} sensitive={entry.sensitive} />
|
||||
{/if}
|
||||
@@ -211,6 +217,7 @@
|
||||
{#if entry.poll}
|
||||
<PollView
|
||||
poll={entry.poll}
|
||||
emojis={entry.poll.emojis?.length ? entry.poll.emojis : entry.emojis}
|
||||
authorId={entry.account.id}
|
||||
onupdate={(poll) => onupdate?.(applyLocal(status, { poll }))}
|
||||
/>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import type { EmojiReaction, Status } from '$lib/api/types'
|
||||
import { useAppServices } from '$lib/app-services'
|
||||
import { safeCustomEmojiUrl } from '$lib/util/html'
|
||||
|
||||
interface Props {
|
||||
status: Status
|
||||
@@ -94,11 +95,12 @@
|
||||
{#if reactions.length > 0}
|
||||
<div class="emoji-reaction-bar" aria-label="Emoji reactions">
|
||||
{#each reactions as reaction (reaction.url ?? reaction.name)}
|
||||
{@const imageUrl = reaction.url ? safeCustomEmojiUrl(reaction.url) : null}
|
||||
<button
|
||||
type="button"
|
||||
class="emoji-reaction"
|
||||
class:emoji-reaction--mine={reaction.me}
|
||||
data-custom={reaction.url ? 'true' : 'false'}
|
||||
data-custom={imageUrl ? 'true' : 'false'}
|
||||
aria-label={accessibleLabel(reaction)}
|
||||
aria-pressed={reaction.me ? 'true' : 'false'}
|
||||
title={session.signedIn
|
||||
@@ -107,10 +109,10 @@
|
||||
disabled={!session.signedIn || busyEmoji !== null}
|
||||
onclick={() => void toggle(reaction)}
|
||||
>
|
||||
{#if reaction.url}
|
||||
{#if imageUrl}
|
||||
<img
|
||||
class="emoji-reaction-image"
|
||||
src={reaction.url}
|
||||
src={imageUrl}
|
||||
alt={customLabel(reaction)}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
<script lang="ts">
|
||||
/** Mastodon/Pleroma poll choices, voting and results. */
|
||||
import { untrack } from 'svelte'
|
||||
import type { Poll } from '$lib/api/types'
|
||||
import type { CustomEmoji, Poll } from '$lib/api/types'
|
||||
import { useAppServices } from '$lib/app-services'
|
||||
import { formatCount } from '$lib/util/profile'
|
||||
import EmojiText from '../common/EmojiText.svelte'
|
||||
|
||||
interface Props {
|
||||
poll: Poll
|
||||
emojis?: CustomEmoji[]
|
||||
authorId?: string
|
||||
onupdate?: (poll: Poll) => void
|
||||
}
|
||||
|
||||
let { poll, authorId, onupdate }: Props = $props()
|
||||
let { poll, emojis = poll.emojis ?? [], authorId, onupdate }: Props = $props()
|
||||
const { endpoints, session } = useAppServices()
|
||||
|
||||
function pollSignature(value: Poll): string {
|
||||
@@ -113,7 +115,7 @@
|
||||
{#if currentPoll.own_votes?.includes(index)}
|
||||
<span class="poll-own-vote" aria-label="Your vote">✓</span>
|
||||
{/if}
|
||||
{option.title}
|
||||
<EmojiText text={option.title} {emojis} />
|
||||
</span>
|
||||
<span class="poll-option-share">
|
||||
{option.votes_count === null ? '—' : `${share(option.votes_count)}%`}
|
||||
@@ -137,7 +139,7 @@
|
||||
{:else}
|
||||
<input type="radio" name={`poll-${currentPoll.id}`} value={index} bind:group={singleChoice} />
|
||||
{/if}
|
||||
<span>{option.title}</span>
|
||||
<EmojiText text={option.title} {emojis} />
|
||||
</label>
|
||||
{/each}
|
||||
</fieldset>
|
||||
|
||||
@@ -91,4 +91,33 @@ describe('PollView', () => {
|
||||
expect(view.getByRole('link', { name: 'Sign in to vote' })).toHaveAttribute('href', '#/login')
|
||||
expect(view.queryByRole('button', { name: 'Vote' })).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('renders custom emoji in poll choices', () => {
|
||||
const view = render(PollView, {
|
||||
props: {
|
||||
poll: poll({
|
||||
options: [
|
||||
{ title: 'Choose :blobcat:', votes_count: null },
|
||||
{ title: 'No thanks', votes_count: null },
|
||||
],
|
||||
emojis: [
|
||||
{
|
||||
shortcode: 'blobcat',
|
||||
url: 'https://cdn.example/blobcat.png',
|
||||
static_url: 'https://cdn.example/blobcat.png',
|
||||
visible_in_picker: true,
|
||||
},
|
||||
],
|
||||
}),
|
||||
authorId: 'someone-else',
|
||||
},
|
||||
context: new Map([[APP_SERVICES, testServices()]]),
|
||||
})
|
||||
|
||||
expect(view.getByAltText(':blobcat:')).toHaveAttribute(
|
||||
'src',
|
||||
'https://cdn.example/blobcat.png',
|
||||
)
|
||||
expect(view.getByRole('radio', { name: 'Choose :blobcat:' })).toBeDisabled()
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user