diff --git a/packages/backend/src/server/FileServerService.ts b/packages/backend/src/server/FileServerService.ts index 8c7d92fc61..54b50041fd 100644 --- a/packages/backend/src/server/FileServerService.ts +++ b/packages/backend/src/server/FileServerService.ts @@ -265,7 +265,8 @@ export class FileServerService { 'avatar' in request.query || 'static' in request.query || 'preview' in request.query || - 'badge' in request.query + 'badge' in request.query || + 'datasaver' in request.query ) { if (!isConvertibleImage) { // 画像でないなら404でお茶を濁す @@ -330,7 +331,28 @@ export class FileServerService { ext: 'png', type: 'image/png', }; - } else if (file.mime === 'image/svg+xml') { + } else if ('datasaver' in request.query){ + if (!isAnimationConvertibleImage && !('static' in request.query)) { + image = { + data: fs.createReadStream(file.path), + ext: file.ext, + type: file.mime, + }; + } else { + const data = (await sharpBmp(file.path, file.mime, { animated: !('static' in request.query) })) + .resize({ + height: 64, + withoutEnlargement: true, + }) + .webp(webpDefault); + + image = { + data, + ext: 'webp', + type: 'image/webp', + }; + } + }else if (file.mime === 'image/svg+xml') { image = this.imageProcessingService.convertToWebpStream(file.path, 2048, 2048); } else if (!file.mime.startsWith('image/') || !FILE_TYPE_BROWSERSAFE.includes(file.mime)) { throw new StatusError('Rejected type', 403, 'Rejected type'); diff --git a/packages/frontend/src/components/global/MkCustomEmoji.vue b/packages/frontend/src/components/global/MkCustomEmoji.vue index bef7c59d77..b01a172a60 100644 --- a/packages/frontend/src/components/global/MkCustomEmoji.vue +++ b/packages/frontend/src/components/global/MkCustomEmoji.vue @@ -38,13 +38,20 @@ const rawUrl = computed(() => { const url = computed(() => { if (rawUrl.value == null) return null; - + const useOriginalSize = props.useOriginalSize; + const enableDataSaverMode = defaultStore.state.enableDataSaverMode; + let datasaver_result ; + if (enableDataSaverMode) { + datasaver_result = useOriginalSize ? undefined : 'datasaver'; + } else { + datasaver_result = useOriginalSize ? undefined : 'emoji'; + } const proxied = (rawUrl.value.startsWith('/emoji/') || (props.useOriginalSize && isLocal.value)) ? rawUrl.value : getProxiedImageUrl( rawUrl.value, - props.useOriginalSize ? undefined : 'emoji', + datasaver_result, false, true, );