From 9a463facce94c66b371dedc54025bcac966ec883 Mon Sep 17 00:00:00 2001 From: Max Litruv Boonzaayer Date: Tue, 21 Apr 2026 21:35:47 +1000 Subject: [PATCH] feat: add Giphy support with embed component and power levels state management --- src/app/components/RenderMessageContent.tsx | 10 ++- src/app/components/create-room/utils.ts | 12 ++++ src/app/components/media/Video.tsx | 18 +++++- .../components/message/MsgTypeRenderers.tsx | 2 +- .../message/attachment/Attachment.css.ts | 5 ++ .../message/attachment/Attachment.tsx | 4 +- .../components/url-preview/GiphyEmbed.css.tsx | 22 +++++++ src/app/components/url-preview/GiphyEmbed.tsx | 64 +++++++++++++++++++ src/app/components/url-preview/index.ts | 1 + src/app/features/call/CallService.ts | 19 ++++++ src/app/features/create-chat/CreateChat.tsx | 3 +- src/app/features/room/RoomView.tsx | 8 ++- src/app/features/room/ThreadView.tsx | 57 +++++++++++++++++ src/app/hooks/useCommands.ts | 4 +- 14 files changed, 218 insertions(+), 11 deletions(-) create mode 100644 src/app/components/url-preview/GiphyEmbed.css.tsx create mode 100644 src/app/components/url-preview/GiphyEmbed.tsx diff --git a/src/app/components/RenderMessageContent.tsx b/src/app/components/RenderMessageContent.tsx index 5da62e0..672dc70 100644 --- a/src/app/components/RenderMessageContent.tsx +++ b/src/app/components/RenderMessageContent.tsx @@ -25,7 +25,7 @@ import { VideoContent, VideoFrameThumbnail, } from './message'; -import { UrlPreviewCard, UrlPreviewHolder, YouTubeEmbed, isYouTubeUrl, TikTokEmbed, isTikTokUrl } from './url-preview'; +import { UrlPreviewCard, UrlPreviewHolder, YouTubeEmbed, isYouTubeUrl, TikTokEmbed, isTikTokUrl, GiphyEmbed, isGiphyUrl } from './url-preview'; import { Image, MediaControl, Video } from './media'; import { ImageViewer } from './image-viewer'; import { PdfViewer } from './Pdf-viewer'; @@ -71,7 +71,8 @@ export function RenderMessageContent({ // Separate special URLs from generic ones const youtubeUrls = filteredUrls.filter(isYouTubeUrl); const tiktokUrls = filteredUrls.filter(isTikTokUrl); - const otherUrls = filteredUrls.filter((url) => !isYouTubeUrl(url) && !isTikTokUrl(url)); + const giphyUrls = filteredUrls.filter(isGiphyUrl); + const otherUrls = filteredUrls.filter((url) => !isYouTubeUrl(url) && !isTikTokUrl(url) && !isGiphyUrl(url)); return ( <> @@ -83,6 +84,10 @@ export function RenderMessageContent({ {tiktokUrls.map((url) => ( ))} + {/* Render Giphy embeds */} + {giphyUrls.map((url) => ( + + ))} {/* Render standard URL previews for other links */} {otherUrls.length > 0 && ( @@ -247,6 +252,7 @@ export function RenderMessageContent({ mimeType={mimeType} url={url} encInfo={encInfo} + autoPlay={mediaAutoLoad} {...props} renderThumbnail={ mediaAutoLoad diff --git a/src/app/components/create-room/utils.ts b/src/app/components/create-room/utils.ts index a0ca748..86091bf 100644 --- a/src/app/components/create-room/utils.ts +++ b/src/app/components/create-room/utils.ts @@ -82,6 +82,16 @@ export const createRoomEncryptionState = () => ({ }, }); +export const createRoomPowerLevelsState = () => ({ + type: StateEvent.RoomPowerLevels, + state_key: '', + content: { + events: { + 'org.matrix.msc3401.call.member': 0, + }, + }, +}); + export type CreateRoomData = { version: string; type?: RoomType; @@ -98,6 +108,8 @@ export type CreateRoomData = { export const createRoom = async (mx: MatrixClient, data: CreateRoomData): Promise => { const initialState: ICreateRoomStateEvent[] = []; + initialState.push(createRoomPowerLevelsState()); + if (data.encryption) { initialState.push(createRoomEncryptionState()); } diff --git a/src/app/components/media/Video.tsx b/src/app/components/media/Video.tsx index 3018347..15d49f3 100644 --- a/src/app/components/media/Video.tsx +++ b/src/app/components/media/Video.tsx @@ -96,7 +96,14 @@ export const Video = forwardRef( if (disableControls) { return ( // eslint-disable-next-line jsx-a11y/media-has-caption -