@zohodesk/dot
Version:
In this Library, we Provide Some Basic Components to Build Your Application
241 lines (209 loc) • 5.64 kB
JavaScript
import { getExtensionFromFileName } 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 checkVideoUrlValidity(url) {
return new Promise(resolve => {
const video = document.createElement('video');
video.src = url;
video.oncanplaythrough = () => resolve(true);
video.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 isValidDocument(url) {
if (!url) {
return false;
}
return true;
}
export const FILE_EXTENSIONS = {
audio: ['mp3', 'wav', 'wma', 'aac', 'm4r', 'm4a', 'flac', 'aiff', 'alac', 'ogg', 'opus', 'amr', 'mid', 'midi'],
video: ['mp4', 'mkv', 'mov', 'mpeg', 'mpg', 'flv', 'wmv', 'avi', 'webm', 'ogv', 'm4v', '3gp', '3g2'],
document: ['doc', 'docx', 'docm', 'dot', 'dotx', 'dotm', 'odt', 'rtf', 'txt', 'md', 'pages', 'xls', 'xlsx', 'xlsm', 'xlsb', 'csv', 'tsv', 'ods', 'sxc', 'numbers', 'ppt', 'pptx', 'pps', 'ppsx', 'pot', 'potx', 'odp', 'sxi', 'key', 'pdf', 'xml', 'json', 'yaml', 'yml', 'log', 'eml', 'msg'],
image: ['jpeg', 'jpg', 'png', 'apng', 'gif', 'bmp', 'dib', 'tiff', 'tif', 'ico', 'svg', 'webp', 'heic', 'heif', 'jfif', 'pjpeg', 'pjp', 'avif']
};
export const SUPPORTED_FILE_EXTENSIONS = {
image: ['jpeg', 'jpg', 'png', 'apng', 'gif', 'bmp', 'tiff', 'tif', 'ico', 'svg', 'heic', 'webp'],
doc: ['txt'],
pdf: ['pdf'],
html: ['html', 'htm', 'xhtml'],
ppt: ['ppt', 'pps', 'odp', 'sxi', 'pptx', 'ppsx', 'pot', 'potx', 'key'],
zip: ['rar', 'jar', 'zip'],
word: ['doc', 'docx', 'sxw', 'odt', 'docm', 'dot', 'dotm', 'dotx', 'rtf', 'pages'],
xml: ['xml'],
sheet: ['xls', 'xlsx', 'xlsm', 'xlsb', 'sxc', 'ods', 'csv', 'tsv', 'numbers'],
audio: ['mp3', 'wav', 'wma', 'aac', 'm4r', 'ogg', 'opus'],
video: ['mp4', 'mkv', 'mov', 'mpeg', 'flv', 'wmv', 'avi', 'webm', 'ogv'],
mail: ['eml', 'msg'],
linux: ['sh', 'bin'],
css: ['css'],
exe: ['exe'],
event: ['ics']
};
export function checkFileSourcesValidation(_ref) {
let {
fileName,
viewURL,
previewUrl,
allowedPreviewExtensionsData
} = _ref;
const extension = (getExtensionFromFileName(fileName) || '').toLowerCase();
if (!extension) {
return Promise.resolve({
isViewURLValid: false,
canZoom: false
});
}
const extensionSource = allowedPreviewExtensionsData || FILE_EXTENSIONS;
const fileExtensionValidation = type => {
const list = extensionSource[type];
if (!Array.isArray(list)) return false;
return list.map(e => e.toLowerCase()).includes(extension);
};
if (fileExtensionValidation('audio')) {
return checkAudioUrlValidity(viewURL).then(isURLValid => {
return {
isViewURLValid: isURLValid,
canZoom: false
};
});
}
if (fileExtensionValidation('video')) {
return checkVideoUrlValidity(viewURL).then(isURLValid => {
return {
isViewURLValid: isURLValid,
canZoom: false
};
});
}
if (fileExtensionValidation('document')) {
const isValid = isValidDocument(previewUrl, fileName);
return Promise.resolve({
isViewURLValid: isValid,
canZoom: false
});
}
if (fileExtensionValidation('image')) {
return checkImageValidity(viewURL).then(isURLValid => {
return {
isViewURLValid: isURLValid,
canZoom: isURLValid
};
});
}
return Promise.resolve({
isViewURLValid: false,
canZoom: false
});
}