All files / src/AttachmentViewer utils.js

13.33% Statements 8/60
8.33% Branches 1/12
16.66% Functions 3/18
14.28% Lines 8/56

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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106                                                                                                                                                  11x 11x 11x   11x   11x                                     2x       2x 2x    
import { isAudioFile } from "./Attachment";
 
export class Zoom {
  constructor() {
    const matrix = [1, 0, 0, 1, 0, 0]; // current view transform
    this.m = matrix;             // alias 
    this.scale = 1;              // current scale
    this.pos = { x: 0, y: 0 }; // current position of origin
    this.dirty = true;
  }
 
  applyTo(el) {
    const { dirty, m } = this;
    if (dirty) {
      this.update(); 
    }
    el.style.transform = `matrix(${m[0]},${m[1]},${m[2]},${m[3]},${m[4]},${m[5]})`;
    el.style.transformOrigin = '0 0';
  }
 
  update() {
    // m[4], m[5] - need to set transforms based on positions. Currently set to 0 to zoom based on center
    const { m, scale, pos } = this;
    this.dirty = false;
    m[3] = m[0] = scale;
    m[2] = m[1] = 0;
    m[4] = pos.x;
    m[5] = pos.y;
  }
 
  pan(amount) {
    if (this.dirty) {
      this.update(); 
    }
    this.pos.x += amount.x;
    this.pos.y += amount.y;
    this.dirty = true;
  }
 
  scaleAt(at, amount) { // at in screen coords
    const { dirty, pos } = this;
    if (dirty) {
      this.update(); 
    }
    this.scale *= amount;
    this.pos.x = at.x - (at.x - pos.x) * amount;
    this.pos.y = at.y - (at.y - pos.y) * amount;
    this.dirty = true;
  }
};
 
export class ZoomEvent {
  constructor() {
    this.pos = [];
  }
 
  on(dir, ele, zoom, event) {
    if (dir === 'in') { 
      const x = event.pageX - (ele.width / 2);
      const y = event.pageY - (ele.height / 2);
      this.pos.push({ x, y });
      zoom.scaleAt({ x, y }, 1.6);
      zoom.applyTo(ele);
    } else if (this.pos.length) { 
      const { x, y } = this.pos.pop();
      zoom.scaleAt({ x, y }, 1/1.6);
      zoom.applyTo(ele);
    } 
    event.preventDefault();
  }  
}
 
export function checkImageValidity(src) {
  return new Promise((resolve) => {
      const img = new Image();
      img.src = src;
 
      img.onload = () => { resolve(true)};
 
      img.onerror = () => { resolve(false) };
  });
}
 
export function checkAudioUrlValidity(url) {
  return new Promise((resolve) => {
    const audio = new Audio(url);
    
    audio.oncanplaythrough = () => {
      resolve(true);
    };
    
    audio.onerror = () => {
      resolve(false);
    };
  });
};
 
export function checkFileSourcesValidation({fileName, viewURL}) {
  Iif(isAudioFile(fileName)){
    const audioValidityPromise = checkAudioUrlValidity(viewURL);
    return audioValidityPromise.then((isURLValid)=>({ isViewURLValid: isURLValid, canZoom: false }))
  }else {
    const imageValidityPromise = checkImageValidity(viewURL);
    return imageValidityPromise.then((isURLValid)=>({ isViewURLValid: isURLValid, canZoom: isURLValid }))
  }
}