2018-03-25 23:09:17 +08:00
|
|
|
function reloadApp() {
|
|
|
|
window.location.reload(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
function parseDate(str) {
|
|
|
|
try {
|
|
|
|
return new Date(Date.parse(str));
|
2018-03-25 11:37:55 +08:00
|
|
|
}
|
2018-03-25 23:09:17 +08:00
|
|
|
catch (e) {
|
|
|
|
throw new Error("Can't parse date from " + str + ": " + e.stack);
|
2018-03-25 11:37:55 +08:00
|
|
|
}
|
2018-03-25 23:09:17 +08:00
|
|
|
}
|
2018-03-25 11:37:55 +08:00
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
function padNum(num) {
|
|
|
|
return (num <= 9 ? "0" : "") + num;
|
|
|
|
}
|
2018-03-25 11:37:55 +08:00
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
function formatTime(date) {
|
|
|
|
return padNum(date.getHours()) + ":" + padNum(date.getMinutes());
|
|
|
|
}
|
2018-03-25 11:37:55 +08:00
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
function formatTimeWithSeconds(date) {
|
|
|
|
return padNum(date.getHours()) + ":" + padNum(date.getMinutes()) + ":" + padNum(date.getSeconds());
|
|
|
|
}
|
2017-12-24 00:02:38 +08:00
|
|
|
|
2019-01-17 05:03:30 +08:00
|
|
|
// this is producing local time!
|
2018-03-25 23:09:17 +08:00
|
|
|
function formatDate(date) {
|
2018-08-15 14:48:16 +08:00
|
|
|
// return padNum(date.getDate()) + ". " + padNum(date.getMonth() + 1) + ". " + date.getFullYear();
|
|
|
|
// instead of european format we'll just use ISO as that's pretty unambiguous
|
|
|
|
|
|
|
|
return formatDateISO(date);
|
2018-03-25 23:09:17 +08:00
|
|
|
}
|
2017-12-24 01:19:15 +08:00
|
|
|
|
2019-01-17 05:03:30 +08:00
|
|
|
// this is producing local time!
|
2018-03-25 23:09:17 +08:00
|
|
|
function formatDateISO(date) {
|
|
|
|
return date.getFullYear() + "-" + padNum(date.getMonth() + 1) + "-" + padNum(date.getDate());
|
|
|
|
}
|
2017-12-24 01:19:15 +08:00
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
function formatDateTime(date) {
|
|
|
|
return formatDate(date) + " " + formatTime(date);
|
|
|
|
}
|
2017-12-29 08:00:31 +08:00
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
function now() {
|
|
|
|
return formatTimeWithSeconds(new Date());
|
|
|
|
}
|
2018-01-23 12:18:08 +08:00
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
function isElectron() {
|
2019-02-10 02:25:55 +08:00
|
|
|
return !!(window && window.process && window.process.type);
|
2018-03-25 23:09:17 +08:00
|
|
|
}
|
2018-01-26 12:49:03 +08:00
|
|
|
|
2018-12-02 21:04:53 +08:00
|
|
|
function isMac() {
|
|
|
|
return navigator.platform.indexOf('Mac') > -1;
|
|
|
|
}
|
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
function assertArguments() {
|
|
|
|
for (const i in arguments) {
|
|
|
|
if (!arguments[i]) {
|
2018-08-07 04:29:03 +08:00
|
|
|
console.trace(`Argument idx#${i} should not be falsy: ${arguments[i]}`);
|
2018-03-25 11:37:55 +08:00
|
|
|
}
|
|
|
|
}
|
2018-03-25 23:09:17 +08:00
|
|
|
}
|
2018-03-07 12:04:35 +08:00
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
function escapeHtml(str) {
|
|
|
|
return $('<div/>').text(str).html();
|
|
|
|
}
|
2018-03-25 11:37:55 +08:00
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
async function stopWatch(what, func) {
|
|
|
|
const start = new Date();
|
2018-03-25 11:37:55 +08:00
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
const ret = await func();
|
2018-02-05 09:23:30 +08:00
|
|
|
|
2019-02-10 23:36:25 +08:00
|
|
|
const tookMs = Date.now() - start.getTime();
|
2018-02-05 09:23:30 +08:00
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
console.log(`${what} took ${tookMs}ms`);
|
2018-02-05 09:23:30 +08:00
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
return ret;
|
|
|
|
}
|
2018-02-20 11:02:03 +08:00
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
function formatValueWithWhitespace(val) {
|
|
|
|
return /[^\w_-]/.test(val) ? '"' + val + '"' : val;
|
|
|
|
}
|
2018-02-22 09:30:15 +08:00
|
|
|
|
2018-04-01 21:59:44 +08:00
|
|
|
function formatLabel(label) {
|
|
|
|
let str = "@" + formatValueWithWhitespace(label.name);
|
2018-03-25 11:37:55 +08:00
|
|
|
|
2018-04-01 21:59:44 +08:00
|
|
|
if (label.value !== "") {
|
|
|
|
str += "=" + formatValueWithWhitespace(label.value);
|
2018-02-20 11:02:03 +08:00
|
|
|
}
|
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getHost() {
|
|
|
|
const url = new URL(window.location.href);
|
|
|
|
return url.protocol + "//" + url.hostname + ":" + url.port;
|
|
|
|
}
|
2018-02-25 23:55:21 +08:00
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
function download(url) {
|
|
|
|
if (isElectron()) {
|
|
|
|
const remote = require('electron').remote;
|
2018-02-25 23:55:21 +08:00
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
remote.getCurrentWebContents().downloadURL(url);
|
2018-02-25 23:55:21 +08:00
|
|
|
}
|
2018-03-25 23:09:17 +08:00
|
|
|
else {
|
|
|
|
window.location.href = url;
|
|
|
|
}
|
|
|
|
}
|
2018-03-05 12:28:26 +08:00
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
function toObject(array, fn) {
|
|
|
|
const obj = {};
|
2018-03-05 12:28:26 +08:00
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
for (const item of array) {
|
2018-03-26 11:25:17 +08:00
|
|
|
const [key, value] = fn(item);
|
2018-03-25 11:37:55 +08:00
|
|
|
|
2018-03-26 11:25:17 +08:00
|
|
|
obj[key] = value;
|
2018-03-05 12:28:26 +08:00
|
|
|
}
|
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
return obj;
|
|
|
|
}
|
2018-03-13 11:27:21 +08:00
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
function randomString(len) {
|
|
|
|
let text = "";
|
|
|
|
const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
2018-03-13 11:27:21 +08:00
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
for (let i = 0; i < len; i++) {
|
|
|
|
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
2018-03-13 11:27:21 +08:00
|
|
|
}
|
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
return text;
|
|
|
|
}
|
|
|
|
|
2019-08-13 04:41:53 +08:00
|
|
|
function bindGlobalShortcut(keyboardShortcut, handler) {
|
2019-05-19 22:56:16 +08:00
|
|
|
bindElShortcut($(document), keyboardShortcut, handler);
|
|
|
|
}
|
|
|
|
|
|
|
|
function bindElShortcut($el, keyboardShortcut, handler) {
|
2018-12-25 01:39:31 +08:00
|
|
|
if (isDesktop()) {
|
2019-01-10 04:42:16 +08:00
|
|
|
if (isMac()) {
|
|
|
|
// use CMD (meta) instead of CTRL for all shortcuts
|
|
|
|
keyboardShortcut = keyboardShortcut.replace("ctrl", "meta");
|
|
|
|
}
|
|
|
|
|
2019-05-19 22:56:16 +08:00
|
|
|
$el.bind('keydown', keyboardShortcut, e => {
|
2018-12-25 01:39:31 +08:00
|
|
|
handler();
|
2018-03-26 07:49:33 +08:00
|
|
|
|
2018-12-25 01:39:31 +08:00
|
|
|
e.preventDefault();
|
|
|
|
});
|
|
|
|
}
|
2018-03-26 07:49:33 +08:00
|
|
|
}
|
|
|
|
|
2018-12-24 17:10:36 +08:00
|
|
|
function isMobile() {
|
2019-01-15 06:50:45 +08:00
|
|
|
return window.device === "mobile"
|
|
|
|
// window.device is not available in setup
|
|
|
|
|| (!window.device && /Mobi/.test(navigator.userAgent));
|
2018-12-24 17:10:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
function isDesktop() {
|
2019-01-15 06:50:45 +08:00
|
|
|
return window.device === "desktop"
|
|
|
|
// window.device is not available in setup
|
|
|
|
|| (!window.device && !/Mobi/.test(navigator.userAgent));
|
2018-12-24 17:10:36 +08:00
|
|
|
}
|
|
|
|
|
2019-03-14 04:53:09 +08:00
|
|
|
// cookie code below works for simple use cases only - ASCII only
|
|
|
|
// not setting path so that cookies do not leak into other websites if multiplexed with reverse proxy
|
|
|
|
|
2018-12-29 07:09:16 +08:00
|
|
|
function setCookie(name, value) {
|
|
|
|
const date = new Date(Date.now() + 10 * 365 * 24 * 60 * 60 * 1000);
|
|
|
|
const expires = "; expires=" + date.toUTCString();
|
|
|
|
|
2019-03-14 04:53:09 +08:00
|
|
|
document.cookie = name + "=" + (value || "") + expires + ";";
|
|
|
|
}
|
|
|
|
|
|
|
|
function setSessionCookie(name, value) {
|
|
|
|
document.cookie = name + "=" + (value || "") + ";";
|
|
|
|
}
|
|
|
|
|
|
|
|
function getCookie(name) {
|
|
|
|
const valueMatch = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
|
|
|
|
return valueMatch ? valueMatch[2] : null;
|
2018-12-29 07:09:16 +08:00
|
|
|
}
|
|
|
|
|
2019-01-29 04:42:37 +08:00
|
|
|
function getNoteTypeClass(type) {
|
|
|
|
return "type-" + type;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getMimeTypeClass(mime) {
|
|
|
|
const semicolonIdx = mime.indexOf(';');
|
|
|
|
|
|
|
|
if (semicolonIdx !== -1) {
|
|
|
|
// stripping everything following the semicolon
|
|
|
|
mime = mime.substr(0, semicolonIdx);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 'mime-' + mime.toLowerCase().replace(/[\W_]+/g,"-");
|
|
|
|
}
|
|
|
|
|
2019-06-11 04:45:03 +08:00
|
|
|
function closeActiveDialog() {
|
|
|
|
if (glob.activeDialog) {
|
|
|
|
glob.activeDialog.modal('hide');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-25 23:09:17 +08:00
|
|
|
export default {
|
|
|
|
reloadApp,
|
|
|
|
parseDate,
|
|
|
|
padNum,
|
|
|
|
formatTime,
|
|
|
|
formatTimeWithSeconds,
|
|
|
|
formatDate,
|
|
|
|
formatDateISO,
|
|
|
|
formatDateTime,
|
|
|
|
now,
|
|
|
|
isElectron,
|
2018-12-02 21:04:53 +08:00
|
|
|
isMac,
|
2018-03-25 23:09:17 +08:00
|
|
|
assertArguments,
|
|
|
|
escapeHtml,
|
|
|
|
stopWatch,
|
|
|
|
formatValueWithWhitespace,
|
|
|
|
formatLabel,
|
|
|
|
getHost,
|
|
|
|
download,
|
|
|
|
toObject,
|
2018-03-26 07:49:33 +08:00
|
|
|
randomString,
|
2019-08-13 04:41:53 +08:00
|
|
|
bindGlobalShortcut,
|
2019-05-19 22:56:16 +08:00
|
|
|
bindElShortcut,
|
2018-12-24 17:10:36 +08:00
|
|
|
isMobile,
|
2018-12-29 07:09:16 +08:00
|
|
|
isDesktop,
|
2019-01-29 04:42:37 +08:00
|
|
|
setCookie,
|
2019-03-14 04:53:09 +08:00
|
|
|
setSessionCookie,
|
|
|
|
getCookie,
|
2019-01-29 04:42:37 +08:00
|
|
|
getNoteTypeClass,
|
2019-06-11 04:45:03 +08:00
|
|
|
getMimeTypeClass,
|
|
|
|
closeActiveDialog
|
2018-03-25 23:09:17 +08:00
|
|
|
};
|