1
0
mirror of https://gitlab.com/timvisee/send.git synced 2024-11-14 07:02:30 +01:00
send/app/utils.js

155 lines
3.5 KiB
JavaScript
Raw Normal View History

const b64 = require('base64-js');
function arrayToB64(array) {
return b64
.fromByteArray(array)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
2017-06-02 05:59:27 +02:00
}
function b64ToArray(str) {
str = (str + '==='.slice((str.length + 3) % 4))
.replace(/-/g, '+')
.replace(/_/g, '/');
return b64.toByteArray(str);
2017-06-02 05:59:27 +02:00
}
2017-06-21 22:23:36 +02:00
function notify(str) {
2017-07-26 20:24:58 +02:00
return str;
/* TODO: enable once we have an opt-in ui element
if (!('Notification' in window)) {
2017-06-21 22:23:36 +02:00
return;
} else if (Notification.permission === 'granted') {
new Notification(str);
2017-06-21 22:23:36 +02:00
} else if (Notification.permission !== 'denied') {
Notification.requestPermission(function(permission) {
if (permission === 'granted') new Notification(str);
});
2017-06-21 22:23:36 +02:00
}
2017-07-26 20:24:58 +02:00
*/
2017-06-21 22:23:36 +02:00
}
function loadShim(polyfill) {
return new Promise((resolve, reject) => {
const shim = document.createElement('script');
shim.src = polyfill;
shim.addEventListener('load', () => resolve(true));
shim.addEventListener('error', () => resolve(false));
document.head.appendChild(shim);
});
}
async function canHasSend(polyfill) {
try {
const key = await window.crypto.subtle.generateKey(
{
name: 'AES-GCM',
length: 128
},
true,
['encrypt', 'decrypt']
);
await window.crypto.subtle.encrypt(
{
name: 'AES-GCM',
iv: window.crypto.getRandomValues(new Uint8Array(12)),
tagLength: 128
},
key,
new ArrayBuffer(8)
);
return true;
2017-07-12 19:53:29 +02:00
} catch (err) {
return loadShim(polyfill);
}
}
function isFile(id) {
return /^[0-9a-fA-F]{10}$/.test(id);
}
2017-08-04 05:13:17 +02:00
function copyToClipboard(str) {
const aux = document.createElement('input');
aux.setAttribute('value', str);
aux.contentEditable = true;
aux.readOnly = true;
document.body.appendChild(aux);
if (navigator.userAgent.match(/iphone|ipad|ipod/i)) {
const range = document.createRange();
range.selectNodeContents(aux);
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
aux.setSelectionRange(0, str.length);
} else {
2017-08-04 05:13:17 +02:00
aux.select();
}
const result = document.execCommand('copy');
2017-08-04 05:13:17 +02:00
document.body.removeChild(aux);
return result;
2017-08-04 05:13:17 +02:00
}
2017-08-06 03:06:43 +02:00
const LOCALIZE_NUMBERS = !!(
typeof Intl === 'object' &&
Intl &&
typeof Intl.NumberFormat === 'function' &&
typeof navigator === 'object'
2017-08-06 03:06:43 +02:00
);
const UNITS = ['B', 'kB', 'MB', 'GB'];
function bytes(num) {
if (num < 1) {
return '0B';
}
2017-08-06 03:06:43 +02:00
const exponent = Math.min(Math.floor(Math.log10(num) / 3), UNITS.length - 1);
const n = Number(num / Math.pow(1000, exponent));
const nStr = LOCALIZE_NUMBERS
? n.toLocaleString(navigator.languages, {
minimumFractionDigits: 1,
maximumFractionDigits: 1
})
: n.toFixed(1);
return `${nStr}${UNITS[exponent]}`;
}
function percent(ratio) {
return LOCALIZE_NUMBERS
? ratio.toLocaleString(navigator.languages, { style: 'percent' })
: `${Math.floor(ratio * 100)}%`;
}
2017-08-11 04:01:39 +02:00
function allowedCopy() {
const support = !!document.queryCommandSupported;
return support ? document.queryCommandSupported('copy') : false;
}
function delay(delay = 100) {
return new Promise(resolve => setTimeout(resolve, delay));
}
function fadeOut(id) {
const classes = document.getElementById(id).classList;
classes.remove('fadeIn');
classes.add('fadeOut');
return delay(300);
}
const ONE_DAY_IN_MS = 86400000;
module.exports = {
fadeOut,
delay,
2017-08-11 04:01:39 +02:00
allowedCopy,
2017-08-06 03:06:43 +02:00
bytes,
percent,
2017-08-04 05:13:17 +02:00
copyToClipboard,
arrayToB64,
b64ToArray,
notify,
canHasSend,
isFile,
ONE_DAY_IN_MS
2017-06-02 05:59:27 +02:00
};