kea-react
Version:
Componentes comunes de react
86 lines (73 loc) • 2.9 kB
text/typescript
import { appendEncodedUrlParameters } from "./url";
export interface Mail {
/**Recipientes To */
to: string[];
/**Recipientes CC */
cc?: string[];
/**Recipientes BCC */
bcc?: string[];
subject?: string;
body?: string;
}
/**Genera la URL del link para un mailto: */
function generateMailtoLinkNoLengthCheck(mail: Mail) {
const generateContactList = (contacts: string[]) => contacts.map(x => x.trim()).join(",");
const base =
"mailto:" + generateContactList(mail.to);
const parameters = ([
{ key: "cc", value: generateContactList(mail.cc || []) },
{ key: "bcc", value: generateContactList(mail.bcc || []) },
{ key: "subject", value: encodeURIComponent(mail.subject || "") },
{ key: "body", value: encodeURIComponent(mail.body || "") }
]).filter(x => !!x.value);
const paramStr = parameters.map(x => x.key + "=" + x.value).join("&");
const url = appendEncodedUrlParameters(base, paramStr);
return url;
}
function getMailLen(mail: Mail) {
const getLen = (x: string | string[] | undefined) => {
if (x == null) return 0;
if (typeof x == "string") return x.length;
return x.map(x => x.length).reduce((a, b) => a + b, 0);
}
return [mail.bcc, mail.body, mail.cc, mail.subject, mail.to].map(x => getLen(x)).reduce((a, b) => a + b, 0);
}
export function generateMailtoLink(mail: Mail) {
const maxLen = 2030;
//Aplicamos una reducción inicial proporcional, intentando atinarle al tamaño del correo
const cutMail = (len: number): Mail => ({
...mail,
body: (mail.body || "").substr(0, len) + "..."
});
let currentMail: Mail = mail;
let currentUrl = generateMailtoLinkNoLengthCheck(currentMail);
let bodyLenFix = (mail.body || "").length;
while (currentUrl.length > maxLen) {
//Reducir la longitud
if (bodyLenFix > 0) {
const mailLen = getMailLen(currentMail);
//La va reduciendo proporcionalmente en cada paso, eso puede ocasionar que sea reducida de mas pero no importa
const reduccionProp = (maxLen / currentUrl.length) * (bodyLenFix / mailLen);
bodyLenFix = Math.ceil(bodyLenFix * reduccionProp) - 1;
} else {
break;
}
currentMail = cutMail(bodyLenFix);
currentUrl = generateMailtoLinkNoLengthCheck(currentMail);
}
return currentUrl;
}
/**
* Envia un correo utilizando la directiva mailto
* @param mail Correo que se desea enviar
*/
export function mailto(mail: Mail) {
const a = document.createElement("a");
a.style.display = "none";
document.body.appendChild(a);
const url = generateMailtoLink(mail);
a.target = "_blank";
a.href = url;
a.click();
document.body.removeChild(a);
}