mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-16 01:26:37 +08:00
feat(server): add image resize support (#14588)
fix #13842 #### PR Dependency Tree * **PR #14588** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Images are now processed natively and converted to WebP for smaller, optimized files; Copilot and avatar attachments use the processed WebP output. * Avatar uploads accept BMP, GIF, JPEG, PNG, WebP (5MB max) and are downscaled to a standard edge. * **Error Messages / i18n** * Added localized error "Image format not supported: {format}". * **Tests** * Added end-to-end and unit tests for conversion, EXIF preservation, and upload limits. * **Chores** * Added native image-processing dependencies. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -24,6 +24,7 @@ import {
|
||||
CopilotProviderSideError,
|
||||
CopilotSessionNotFound,
|
||||
type FileUpload,
|
||||
ImageFormatNotSupported,
|
||||
paginate,
|
||||
Paginated,
|
||||
PaginationInput,
|
||||
@@ -39,6 +40,7 @@ import { DocReader } from '../../core/doc';
|
||||
import { AccessController, DocAction } from '../../core/permission';
|
||||
import { UserType } from '../../core/user';
|
||||
import type { ListSessionOptions, UpdateChatSession } from '../../models';
|
||||
import { processImage } from '../../native';
|
||||
import { CopilotCronJobs } from './cron';
|
||||
import { PromptService } from './prompt/service';
|
||||
import { CopilotProviderFactory } from './providers/factory';
|
||||
@@ -48,6 +50,7 @@ import { CopilotStorage } from './storage';
|
||||
import { type ChatHistory, type ChatMessage, SubmittedMessage } from './types';
|
||||
|
||||
export const COPILOT_LOCKER = 'copilot';
|
||||
const COPILOT_IMAGE_MAX_EDGE = 1536;
|
||||
|
||||
// ================== Input Types ==================
|
||||
|
||||
@@ -777,19 +780,35 @@ export class CopilotResolver {
|
||||
|
||||
for (const blob of blobs) {
|
||||
const uploaded = await this.storage.handleUpload(user.id, blob);
|
||||
const detectedMime =
|
||||
sniffMime(uploaded.buffer, blob.mimetype)?.toLowerCase() ||
|
||||
blob.mimetype;
|
||||
let attachmentBuffer = uploaded.buffer;
|
||||
let attachmentMimeType = detectedMime;
|
||||
|
||||
if (detectedMime.startsWith('image/')) {
|
||||
try {
|
||||
attachmentBuffer = await processImage(
|
||||
uploaded.buffer,
|
||||
COPILOT_IMAGE_MAX_EDGE,
|
||||
true
|
||||
);
|
||||
attachmentMimeType = 'image/webp';
|
||||
} catch {
|
||||
throw new ImageFormatNotSupported({ format: detectedMime });
|
||||
}
|
||||
}
|
||||
|
||||
const filename = createHash('sha256')
|
||||
.update(uploaded.buffer)
|
||||
.update(attachmentBuffer)
|
||||
.digest('base64url');
|
||||
const attachment = await this.storage.put(
|
||||
user.id,
|
||||
workspaceId,
|
||||
filename,
|
||||
uploaded.buffer
|
||||
attachmentBuffer
|
||||
);
|
||||
attachments.push({
|
||||
attachment,
|
||||
mimeType: sniffMime(uploaded.buffer, blob.mimetype) || blob.mimetype,
|
||||
});
|
||||
attachments.push({ attachment, mimeType: attachmentMimeType });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user