Add emoji confetti bursts and component playground.

Support app.relay.emoji_confetti on jumbo emoji clicks with canvas physics,
per-emoji particle profiles, and a fixed overlay that does not affect scroll.
Also add a Vite playground for live component previews and theme hover preview.
This commit is contained in:
2026-07-29 20:40:36 +10:00
parent ea7642f0bb
commit 0da4f0d6cb
48 changed files with 3689 additions and 46 deletions

View File

@@ -65,6 +65,8 @@ import * as roomViewCss from './RoomViewFollowing.css';
import { Message, Reactions, EncryptedContent } from './message';
import { Reply } from '../../components/message';
import { RenderMessageContent } from '../../components/RenderMessageContent';
import { EmojiConfettiOverlay } from './emoji-confetti/EmojiConfettiOverlay';
import { useJumboEmojiConfetti } from './emoji-confetti/useJumboEmojiConfetti';
import {
LINKIFY_OPTS,
factoryRenderLinkifyWithMention,
@@ -156,6 +158,8 @@ export function ThreadView({ room, threadRootId }: ThreadViewProps) {
const [hour24Clock] = useSetting(settingsAtom, 'hour24Clock');
const [dateFormatString] = useSetting(settingsAtom, 'dateFormatString');
const [hideActivity] = useSetting(settingsAtom, 'hideActivity');
const { bursts: emojiConfettiBursts, removeBurst: removeEmojiConfettiBurst, handleJumboEmojiClick } =
useJumboEmojiConfetti(room);
const showUrlPreview = room.hasEncryptionStateEvent() ? encUrlPreview : urlPreview;
const direct = useIsDirectRoom();
@@ -638,6 +642,8 @@ export function ThreadView({ room, threadRootId }: ThreadViewProps) {
linkifyOpts={linkifyOpts}
outlineAttachment={messageLayout === MessageLayout.Bubble}
disabledEmbedPatterns={combinedEmbedFilters}
targetEventId={mEventId}
onJumboEmojiClick={handleJumboEmojiClick}
/>
)}
</EncryptedContent>
@@ -654,6 +660,8 @@ export function ThreadView({ room, threadRootId }: ThreadViewProps) {
linkifyOpts={linkifyOpts}
outlineAttachment={messageLayout === MessageLayout.Bubble}
disabledEmbedPatterns={combinedEmbedFilters}
targetEventId={mEventId}
onJumboEmojiClick={handleJumboEmojiClick}
/>
)}
</Message>
@@ -759,6 +767,10 @@ export function ThreadView({ room, threadRootId }: ThreadViewProps) {
{events.map((evt, idx, arr) => renderEvent(evt, idx, arr))}
</Box>
</Scroll>
<EmojiConfettiOverlay
bursts={emojiConfettiBursts}
onBurstComplete={removeEmojiConfettiBurst}
/>
</Box>
<div className={roomViewCss.RoomViewBottomFloat}>
<RoomViewTyping room={room} />