snappymail/dev/Model/Attachment.jsx

488 lines
11 KiB
React
Raw Normal View History

2016-07-07 05:03:30 +08:00
import window from 'window';
import _ from '_';
import ko from 'ko';
import {FileType} from 'Common/Enums';
import {bAllowPdfPreview, data as GlobalsData} from 'Common/Globals';
import {trim, pInt, inArray, isNonEmptyArray, getFileExtension, friendlySize} from 'Common/Utils';
import {attachmentDownload, attachmentPreview, attachmentFramed, attachmentPreviewAsPlain, attachmentThumbnailPreview} from 'Common/Links';
import {AbstractModel} from 'Knoin/AbstractModel';
import Audio from 'Common/Audio';
/**
* @param {string} sExt
* @param {string} sMimeType
* @returns {string}
*/
export const staticFileType = _.memoize((ext, mimeType) => {
ext = trim(ext).toLowerCase();
mimeType = trim(mimeType).toLowerCase();
let result = FileType.Unknown;
const mimeTypeParts = mimeType.split('/');
switch (true)
{
case 'image' === mimeTypeParts[0] || -1 < inArray(ext, [
'png', 'jpg', 'jpeg', 'gif', 'bmp'
]):
result = FileType.Image;
break;
case 'audio' === mimeTypeParts[0] || -1 < inArray(ext, [
'mp3', 'ogg', 'oga', 'wav'
]):
result = FileType.Audio;
break;
case 'video' === mimeTypeParts[0] || -1 < inArray(ext, [
'mkv', 'avi'
]):
result = FileType.Video;
break;
case -1 < inArray(ext, [
'php', 'js', 'css'
]):
result = FileType.Code;
break;
case 'eml' === ext || -1 < inArray(mimeType, [
'message/delivery-status', 'message/rfc822'
]):
result = FileType.Eml;
break;
case ('text' === mimeTypeParts[0] && 'html' !== mimeTypeParts[1]) || -1 < inArray(ext, [
'txt', 'log'
]):
result = FileType.Text;
break;
case ('text/html' === mimeType) || -1 < inArray(ext, [
'html'
]):
result = FileType.Html;
break;
case -1 < inArray(mimeTypeParts[1], [
'zip', '7z', 'tar', 'rar', 'gzip', 'bzip', 'bzip2', 'x-zip', 'x-7z', 'x-rar', 'x-tar', 'x-gzip', 'x-bzip', 'x-bzip2', 'x-zip-compressed', 'x-7z-compressed', 'x-rar-compressed'
]) || -1 < inArray(ext, [
'zip', '7z', 'tar', 'rar', 'gzip', 'bzip', 'bzip2'
]):
result = FileType.Archive;
break;
case -1 < inArray(mimeTypeParts[1], ['pdf', 'x-pdf']) || -1 < inArray(ext, [
'pdf'
]):
result = FileType.Pdf;
break;
case -1 < inArray(mimeType, [
'application/pgp-signature', 'application/pgp-keys'
]) || -1 < inArray(ext, [
'asc', 'pem', 'ppk'
]):
result = FileType.Certificate;
break;
case -1 < inArray(mimeType, ['application/pkcs7-signature']) ||
-1 < inArray(ext, ['p7s']):
result = FileType.CertificateBin;
break;
case -1 < inArray(mimeTypeParts[1], [
'rtf', 'msword', 'vnd.msword', 'vnd.openxmlformats-officedocument.wordprocessingml.document',
'vnd.openxmlformats-officedocument.wordprocessingml.template',
'vnd.ms-word.document.macroEnabled.12',
'vnd.ms-word.template.macroEnabled.12'
]):
result = FileType.WordText;
break;
case -1 < inArray(mimeTypeParts[1], [
'excel', 'ms-excel', 'vnd.ms-excel',
'vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'vnd.openxmlformats-officedocument.spreadsheetml.template',
'vnd.ms-excel.sheet.macroEnabled.12',
'vnd.ms-excel.template.macroEnabled.12',
'vnd.ms-excel.addin.macroEnabled.12',
'vnd.ms-excel.sheet.binary.macroEnabled.12'
]):
result = FileType.Sheet;
break;
case -1 < inArray(mimeTypeParts[1], [
'powerpoint', 'ms-powerpoint', 'vnd.ms-powerpoint',
'vnd.openxmlformats-officedocument.presentationml.presentation',
'vnd.openxmlformats-officedocument.presentationml.template',
'vnd.openxmlformats-officedocument.presentationml.slideshow',
'vnd.ms-powerpoint.addin.macroEnabled.12',
'vnd.ms-powerpoint.presentation.macroEnabled.12',
'vnd.ms-powerpoint.template.macroEnabled.12',
'vnd.ms-powerpoint.slideshow.macroEnabled.12'
]):
result = FileType.Presentation;
break;
// no default
}
return result;
});
/**
* @param {string} sFileType
* @returns {string}
*/
export const staticIconClass = _.memoize((fileType) => {
let
resultText = '',
resultClass = 'icon-file';
switch (fileType)
{
case FileType.Text:
case FileType.Eml:
case FileType.WordText:
resultClass = 'icon-file-text';
break;
case FileType.Html:
case FileType.Code:
resultClass = 'icon-file-code';
break;
case FileType.Image:
resultClass = 'icon-file-image';
break;
case FileType.Audio:
resultClass = 'icon-file-music';
break;
case FileType.Video:
resultClass = 'icon-file-movie';
break;
case FileType.Archive:
resultClass = 'icon-file-zip';
break;
case FileType.Certificate:
case FileType.CertificateBin:
resultClass = 'icon-file-certificate';
break;
case FileType.Sheet:
resultClass = 'icon-file-excel';
break;
case FileType.Presentation:
resultClass = 'icon-file-chart-graph';
break;
case FileType.Pdf:
resultText = 'pdf';
resultClass = 'icon-none';
break;
// no default
}
return [resultClass, resultText];
});
/**
* @static
* @param {string} sFileType
* @returns {string}
*/
export const staticCombinedIconClass = (data) => {
let
result = '',
types = [];
if (isNonEmptyArray(data))
{
result = 'icon-attachment';
types = _.uniq(_.compact(_.map(data, (item) => (item ? staticFileType(getFileExtension(item[0]), item[1]) : ''))));
if (types && 1 === types.length && types[0])
{
switch (types[0])
{
case FileType.Text:
case FileType.WordText:
result = 'icon-file-text';
break;
case FileType.Html:
case FileType.Code:
result = 'icon-file-code';
break;
case FileType.Image:
result = 'icon-file-image';
break;
case FileType.Audio:
result = 'icon-file-music';
break;
case FileType.Video:
result = 'icon-file-movie';
break;
case FileType.Archive:
result = 'icon-file-zip';
break;
case FileType.Certificate:
case FileType.CertificateBin:
result = 'icon-file-certificate';
break;
case FileType.Sheet:
result = 'icon-file-excel';
break;
case FileType.Presentation:
result = 'icon-file-chart-graph';
break;
// no default
}
}
}
return result;
};
class AttachmentModel extends AbstractModel
{
constructor()
{
super('AttachmentModel');
this.checked = ko.observable(false);
this.mimeType = '';
this.fileName = '';
this.fileNameExt = '';
this.fileType = FileType.Unknown;
this.estimatedSize = 0;
this.friendlySize = '';
this.isInline = false;
this.isLinked = false;
this.isThumbnail = false;
this.cid = '';
this.cidWithOutTags = '';
this.contentLocation = '';
this.download = '';
this.folder = '';
this.uid = '';
this.mimeIndex = '';
this.framed = false;
}
/**
* @static
* @param {AjaxJsonAttachment} json
* @returns {?AttachmentModel}
*/
static newInstanceFromJson(json) {
const attachment = new AttachmentModel();
return attachment.initByJson(json) ? attachment : null;
}
/**
* @param {AjaxJsonAttachment} json
* @returns {boolean}
*/
initByJson(json) {
let bResult = false;
if (json && 'Object/Attachment' === json['@Object'])
{
this.mimeType = trim((json.MimeType || '').toLowerCase());
this.fileName = trim(json.FileName);
this.estimatedSize = pInt(json.EstimatedSize);
this.isInline = !!json.IsInline;
this.isLinked = !!json.IsLinked;
this.isThumbnail = !!json.IsThumbnail;
this.cid = json.CID;
this.contentLocation = json.ContentLocation;
this.download = json.Download;
this.folder = json.Folder;
this.uid = json.Uid;
this.mimeIndex = json.MimeIndex;
this.framed = !!json.Framed;
this.friendlySize = friendlySize(this.estimatedSize);
this.cidWithOutTags = this.cid.replace(/^<+/, '').replace(/>+$/, '');
this.fileNameExt = getFileExtension(this.fileName);
this.fileType = staticFileType(this.fileNameExt, this.mimeType);
bResult = true;
}
return bResult;
}
/**
* @returns {boolean}
*/
isImage() {
return FileType.Image === this.fileType;
}
/**
* @returns {boolean}
*/
isMp3() {
return FileType.Audio === this.fileType && 'mp3' === this.fileNameExt;
}
/**
* @returns {boolean}
*/
isOgg() {
return FileType.Audio === this.fileType && ('oga' === this.fileNameExt || 'ogg' === this.fileNameExt);
}
/**
* @returns {boolean}
*/
isWav() {
return FileType.Audio === this.fileType && 'wav' === this.fileNameExt;
}
/**
* @returns {boolean}
*/
hasThumbnail() {
return this.isThumbnail;
}
/**
* @returns {boolean}
*/
isText() {
return FileType.Text === this.fileType || FileType.Eml === this.fileType ||
FileType.Certificate === this.fileType || FileType.Html === this.fileType || FileType.Code === this.fileType;
}
/**
* @returns {boolean}
*/
isPdf() {
return FileType.Pdf === this.fileType;
}
/**
* @returns {boolean}
*/
isFramed() {
return this.framed && (GlobalsData.__APP__ && GlobalsData.__APP__.googlePreviewSupported()) &&
!(this.isPdf() && bAllowPdfPreview) && !this.isText() && !this.isImage();
}
/**
* @returns {boolean}
*/
hasPreview() {
return this.isImage() || (this.isPdf() && bAllowPdfPreview) || this.isText() || this.isFramed();
}
/**
* @returns {boolean}
*/
hasPreplay() {
return (Audio.supportedMp3 && this.isMp3()) || (Audio.supportedOgg && this.isOgg()) || (Audio.supportedWav && this.isWav());
}
/**
* @returns {string}
*/
linkDownload() {
return attachmentDownload(this.download);
}
/**
* @returns {string}
*/
linkPreview() {
return attachmentPreview(this.download);
}
/**
* @returns {string}
*/
linkThumbnail() {
return this.hasThumbnail() ? attachmentThumbnailPreview(this.download) : '';
}
/**
* @returns {string}
*/
linkThumbnailPreviewStyle() {
const link = this.linkThumbnail();
return '' === link ? '' : 'background:url(' + link + ')';
}
/**
* @returns {string}
*/
linkFramed() {
return attachmentFramed(this.download);
}
/**
* @returns {string}
*/
linkPreviewAsPlain() {
return attachmentPreviewAsPlain(this.download);
}
/**
* @returns {string}
*/
linkPreviewMain() {
let result = '';
switch (true)
{
case this.isImage():
case this.isPdf() && bAllowPdfPreview:
result = this.linkPreview();
break;
case this.isText():
result = this.linkPreviewAsPlain();
break;
case this.isFramed():
result = this.linkFramed();
break;
// no default
}
return result;
}
/**
* @returns {string}
*/
generateTransferDownloadUrl() {
let link = this.linkDownload();
if ('http' !== link.substr(0, 4))
{
link = window.location.protocol + '//' + window.location.host + window.location.pathname + link;
}
return this.mimeType + ':' + this.fileName + ':' + link;
}
/**
* @param {AttachmentModel} attachment
* @param {*} event
* @returns {boolean}
*/
eventDragStart(attachment, event) {
const localEvent = event.originalEvent || event;
if (attachment && localEvent && localEvent.dataTransfer && localEvent.dataTransfer.setData)
{
localEvent.dataTransfer.setData('DownloadURL', this.generateTransferDownloadUrl());
}
return true;
}
/**
* @returns {string}
*/
iconClass() {
return staticIconClass(this.fileType)[0];
}
/**
* @returns {string}
*/
iconText() {
return staticIconClass(this.fileType)[1];
}
}
export {AttachmentModel, AttachmentModel as default};