From 347920bfecf2ad517087dfe72849f888f10f910a Mon Sep 17 00:00:00 2001 From: Erwan Leboucher Date: Sat, 25 Jul 2026 11:58:42 +0200 Subject: [PATCH 1/2] fix(sticker): send using the pack's image info instead of downloading the sticker --- .changeset/sticker-send-pack-info.md | 5 +++++ src/app/features/room/RoomInput.tsx | 27 +++++++++++++++++++++------ src/app/plugins/custom-emoji/utils.ts | 19 +++++++++++++++++++ 3 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 .changeset/sticker-send-pack-info.md diff --git a/.changeset/sticker-send-pack-info.md b/.changeset/sticker-send-pack-info.md new file mode 100644 index 0000000000..39f5be16a4 --- /dev/null +++ b/.changeset/sticker-send-pack-info.md @@ -0,0 +1,5 @@ +--- +default: patch +--- + +Fix tapping a sticker silently not sending it. diff --git a/src/app/features/room/RoomInput.tsx b/src/app/features/room/RoomInput.tsx index af028c8db3..f8c3df24a2 100644 --- a/src/app/features/room/RoomInput.tsx +++ b/src/app/features/room/RoomInput.tsx @@ -191,6 +191,7 @@ import { getImagePackReferencesForMxcWrappedInMap, } from '$utils/msc4459helper'; import { ImageUsage } from '$plugins/custom-emoji'; +import { getPackImageInfo } from '$plugins/custom-emoji/utils'; import { SerializableMap } from '$types/wrapper/SerializableMap'; import { useSettingsLinkBaseUrl } from '$features/settings/useSettingsLinkBaseUrl'; import { AttachmentSheet } from '$components/attachment-sheet/AttachmentSheet'; @@ -1746,16 +1747,26 @@ export const RoomInput = forwardRef( }; const handleStickerSelect = async (mxc: string, shortcode: string, label: string) => { - const stickerUrl = mxcUrlToHttp(mx, mxc, useAuthentication); - if (!stickerUrl) return; + // Packs declare their own info, so sending does not need the file. Measuring it instead made + // the send fail outright whenever the media fetch did. + let info = getPackImageInfo(mx, room, ImageUsage.Sticker, mxc); - const { blob, image } = await loadImageElementFromMediaUrl(stickerUrl); - const info = getImageInfo(image, blob); + if (!info) { + const stickerUrl = mxcUrlToHttp(mx, mxc, useAuthentication); + if (stickerUrl) { + try { + const { blob, image } = await loadImageElementFromMediaUrl(stickerUrl); + info = getImageInfo(image, blob); + } catch (error) { + log.error('failed to measure sticker, sending without info', { mxc }, error); + } + } + } const content: StickerEventContent & ReplyEventContent & IContent & IGenericMSC4459 = { body: label, url: mxc, - info, + info: info ?? {}, }; // add the image pack reference @@ -1784,7 +1795,11 @@ export const RoomInput = forwardRef( content['m.mentions'] = { ['user_ids']: [replyDraft.userId] }; setReplyDraft(replyDraftBase); } - mx.sendEvent(roomId, EventType.Sticker, content); + try { + await mx.sendEvent(roomId, EventType.Sticker, content); + } catch (error) { + log.error('failed to send sticker', { roomId }, error); + } }; const handleGifSelect = async (gif: GifData, spoiler?: boolean) => { diff --git a/src/app/plugins/custom-emoji/utils.ts b/src/app/plugins/custom-emoji/utils.ts index 318a2a4e6d..433b7b21b6 100644 --- a/src/app/plugins/custom-emoji/utils.ts +++ b/src/app/plugins/custom-emoji/utils.ts @@ -2,6 +2,7 @@ import type { MatrixClient, MatrixEvent, Room } from '$types/matrix-sdk'; import { getAccountData, getStateEvent, getStateEvents } from '$utils/room'; +import type { IImageInfo } from '$types/matrix/common'; import type { ImageUsage } from './types'; import { ImagePack } from './ImagePack'; import type { PackMetaReader } from './PackMetaReader'; @@ -127,3 +128,21 @@ export function getUserImagePack(mx: MatrixClient): ImagePack | undefined { const userImagePack = ImagePack.fromMatrixEvent(userId, packEvent); return userImagePack; } + +/** + * The info a pack declares for one of its images: dimensions, mimetype and size, so sending a pack + * image never requires downloading it first. + */ +export function getPackImageInfo( + mx: MatrixClient, + room: Room, + usage: ImageUsage, + mxcUrl: string +): IImageInfo | undefined { + const packs = [...getRoomImagePacks(room), ...getGlobalImagePacks(mx)]; + for (const pack of packs) { + const info = pack.getImages(usage).find((image) => image.url === mxcUrl)?.info; + if (info) return info; + } + return undefined; +} From 3785159460fe45483e30cba099bce009db1eac7b Mon Sep 17 00:00:00 2001 From: 7w1 Date: Sat, 25 Jul 2026 15:53:05 -0500 Subject: [PATCH 2/2] fix: include user image packs --- src/app/plugins/custom-emoji/utils.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/app/plugins/custom-emoji/utils.ts b/src/app/plugins/custom-emoji/utils.ts index 433b7b21b6..171acadcd5 100644 --- a/src/app/plugins/custom-emoji/utils.ts +++ b/src/app/plugins/custom-emoji/utils.ts @@ -139,7 +139,12 @@ export function getPackImageInfo( usage: ImageUsage, mxcUrl: string ): IImageInfo | undefined { - const packs = [...getRoomImagePacks(room), ...getGlobalImagePacks(mx)]; + const userPack = getUserImagePack(mx); + const packs = [ + ...getRoomImagePacks(room), + ...(userPack ? [userPack] : []), + ...getGlobalImagePacks(mx), + ]; for (const pack of packs) { const info = pack.getImages(usage).find((image) => image.url === mxcUrl)?.info; if (info) return info;