1
0
Fork 0

Might as well go further into custom emoji reactions

But still MVP-ish. Misskey emoji shortcodes ain't going to work tho'
This commit is contained in:
Lim Chee Aun 2024-03-25 17:58:56 +08:00
parent 39800e771c
commit c9bbca9e11
5 changed files with 99 additions and 19 deletions

View file

@ -0,0 +1,17 @@
export default function CustomEmoji({ staticUrl, alt, url }) {
return (
<picture>
<source srcset={staticUrl} media="(prefers-reduced-motion: reduce)" />
<img
key={alt}
src={url}
alt={alt}
class="shortcode-emoji emoji"
width="16"
height="16"
loading="lazy"
decoding="async"
/>
</picture>
);
}

View file

@ -1,5 +1,7 @@
import { memo } from 'preact/compat';
import CustomEmoji from './custom-emoji';
function EmojiText({ text, emojis }) {
if (!text) return '';
if (!emojis?.length) return text;
@ -12,21 +14,7 @@ function EmojiText({ text, emojis }) {
const emoji = emojis.find((e) => e.shortcode === word);
if (emoji) {
const { url, staticUrl } = emoji;
return (
<picture>
<source srcset={staticUrl} media="(prefers-reduced-motion: reduce)" />
<img
key={word}
src={url}
alt={word}
class="shortcode-emoji emoji"
width="16"
height="16"
loading="lazy"
decoding="async"
/>
</picture>
);
return <CustomEmoji staticUrl={staticUrl} alt={word} url={url} />;
}
return word;
});

View file

@ -7,6 +7,7 @@ import store from '../utils/store';
import useTruncated from '../utils/useTruncated';
import Avatar from './avatar';
import CustomEmoji from './custom-emoji';
import FollowRequestButtons from './follow-request-buttons';
import Icon from './icon';
import Link from './link';
@ -45,6 +46,24 @@ admin.sign_up = Someone signed up (optionally sent to admins)
admin.report = A new report has been filed
*/
function emojiText(emoji, emoji_url) {
let url;
let staticUrl;
if (typeof emoji_url === 'string') {
url = emoji_url;
} else {
url = emoji_url?.url;
staticUrl = emoji_url?.staticUrl;
}
return url ? (
<>
reacted to your post with{' '}
<CustomEmoji url={url} staticUrl={staticUrl} alt={emoji} />
</>
) : (
`reacted to your post with ${emoji}.`
);
}
const contentText = {
mention: 'mentioned you in their post.',
status: 'published a post.',
@ -67,8 +86,8 @@ const contentText = {
'admin.sign_up': 'signed up.',
'admin.report': (targetAccount) => <>reported {targetAccount}</>,
severed_relationships: (name) => `Relationships with ${name} severed.`,
emoji_reaction: (emoji) => `reacted to your post with ${emoji}.`,
'pleroma:emoji_reaction': (emoji) => `reacted to your post with ${emoji}.`,
emoji_reaction: emojiText,
'pleroma:emoji_reaction': emojiText,
};
// account_suspension, domain_block, user_domain_block
@ -156,7 +175,14 @@ function Notification({
(type === 'emoji_reaction' || type === 'pleroma:emoji_reaction') &&
notification.emoji
) {
text = text(notification.emoji);
const emojiURL =
notification.emoji_url || // This is string
status?.emojis?.find?.(
(emoji) =>
emoji?.shortcode ===
notification.emoji.replace(/^:/, '').replace(/:$/, ''),
); // Emoji object instead of string
text = text(notification.emoji, emojiURL);
} else if (count) {
text = text(count);
}

View file

@ -1753,6 +1753,13 @@ a.card:is(:hover, :focus):visited {
margin-left: calc(-50px - 16px);
}
/* EMOJI REACTIONS */
.status.large .emoji-reactions {
cursor: default;
margin-left: calc(-50px - 16px);
}
/* ACTIONS */
.status .actions {

View file

@ -24,7 +24,7 @@ import { useHotkeys } from 'react-hotkeys-hook';
import { useLongPress } from 'use-long-press';
import { useSnapshot } from 'valtio';
import AccountBlock from '../components/account-block';
import CustomEmoji from '../components/custom-emoji';
import EmojiText from '../components/emoji-text';
import Loader from '../components/loader';
import Menu2 from '../components/menu2';
@ -241,6 +241,8 @@ function Status({
_deleted,
_pinned,
// _filtered,
// Non-Mastodon
emojiReactions,
} = status;
const currentAccount = useMemo(() => {
@ -1929,6 +1931,46 @@ function Status({
</>
)}
</div>
{!!emojiReactions?.length && (
<div class="emoji-reactions">
{emojiReactions.map((emojiReaction) => {
const { name, count, me } = emojiReaction;
const isShortCode = /^:.+?:$/.test(name);
if (isShortCode) {
const emoji = emojis.find(
(e) =>
e.shortcode ===
name.replace(/^:/, '').replace(/:$/, ''),
);
if (emoji) {
return (
<span
class={`emoji-reaction tag ${
me ? '' : 'insignificant'
}`}
>
<CustomEmoji
alt={name}
url={emoji.url}
staticUrl={emoji.staticUrl}
/>
{count}
</span>
);
}
}
return (
<span
class={`emoji-reaction tag ${
me ? '' : 'insignificant'
}`}
>
{name} {count}
</span>
);
})}
</div>
)}
<div class={`actions ${_deleted ? 'disabled' : ''}`}>
<div class="action has-count">
<StatusButton