All files / src/app/extensions/copilot-embedded/models/copilot-embedded-upload copilot-embedded-upload.helper.ts

100% Statements 28/28
100% Branches 3/3
100% Functions 8/8
100% Lines 27/27

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54    3x   3x   3x               6x 6x 6x 5x 5x 5x 5x 5x 5x 1x 1x     4x 4x 4x 4x   6x 6x               2x 2x 2x 1x 1x 1x     2x        
import { CopilotEmbeddedUpload } from './copilot-embedded-upload.model';
 
const THUMBNAIL_MAX_SIZE = 200;
 
const THUMBNAIL_QUALITY = 0.7;
 
export class CopilotEmbeddedUploadHelper {
  /**
   * Converts an image data URL to a small JPEG data URL (longest side at most `maxSize` px), so it
   * can be persisted with the chat transcript without filling up localStorage.
   *
   * Resolves `undefined` when the image cannot be decoded or the browser has no canvas support.
   */
  static createImageThumbnail(dataUrl: string, maxSize = THUMBNAIL_MAX_SIZE): Promise<string> {
    return new Promise(resolve => {
      const image = new Image();
      image.onload = () => {
        const scale = Math.min(1, maxSize / Math.max(image.width, image.height));
        const canvas = document.createElement('canvas');
        canvas.width = Math.max(1, Math.round(image.width * scale));
        canvas.height = Math.max(1, Math.round(image.height * scale));
        const context = canvas.getContext('2d');
        if (!context) {
          resolve(undefined);
          return;
        }
        // JPEG has no alpha channel; without a background transparent areas turn black
        context.fillStyle = '#fff';
        context.fillRect(0, 0, canvas.width, canvas.height);
        context.drawImage(image, 0, 0, canvas.width, canvas.height);
        resolve(canvas.toDataURL('image/jpeg', THUMBNAIL_QUALITY));
      };
      image.onerror = () => resolve(undefined);
      image.src = dataUrl;
    });
  }
 
  /**
   * Reads an image file into a base64 data URL upload for the chatflow, together with a small thumbnail of it.
   */
  static readImageUpload(file: File): Promise<{ upload: CopilotEmbeddedUpload; thumbnail: string }> {
    return new Promise(resolve => {
      const reader = new FileReader();
      reader.onload = () => {
        const data = reader.result as string;
        CopilotEmbeddedUploadHelper.createImageThumbnail(data).then(thumbnail =>
          resolve({ upload: { data, type: 'file', name: file.name, mime: file.type }, thumbnail })
        );
      };
      reader.readAsDataURL(file);
    });
  }
}