2021-03-04 15:28:33 +00:00
|
|
|
import clipboardCopy from 'clipboard-copy';
|
|
|
|
|
2020-05-18 12:07:09 +00:00
|
|
|
/**
|
|
|
|
* A helper function that behaves similar to Object.assign, but only reassigns a
|
|
|
|
* property in target if it's defined in source.
|
|
|
|
*
|
|
|
|
* @param {Object} target - The target object to assign the values into.
|
|
|
|
* @param {Object} source - The source object.
|
|
|
|
* @returns {Object}
|
|
|
|
*/
|
|
|
|
export function assignIfDefined(target: Object, source: Object) {
|
|
|
|
const to = Object(target);
|
|
|
|
|
|
|
|
for (const nextKey in source) {
|
|
|
|
if (source.hasOwnProperty(nextKey)) {
|
2022-07-29 13:18:14 +00:00
|
|
|
const value = source[nextKey as keyof typeof source];
|
2020-05-18 12:07:09 +00:00
|
|
|
|
|
|
|
if (typeof value !== 'undefined') {
|
|
|
|
to[nextKey] = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return to;
|
|
|
|
}
|
|
|
|
|
2020-06-24 07:34:00 +00:00
|
|
|
/**
|
|
|
|
* Tries to copy a given text to the clipboard.
|
|
|
|
* Returns true if the action succeeds.
|
|
|
|
*
|
|
|
|
* @param {string} textToCopy - Text to be copied.
|
2021-03-03 21:04:00 +00:00
|
|
|
* @returns {Promise<boolean>}
|
2020-06-24 07:34:00 +00:00
|
|
|
*/
|
2021-02-24 15:12:41 +00:00
|
|
|
export async function copyText(textToCopy: string) {
|
2020-06-24 07:34:00 +00:00
|
|
|
try {
|
2021-03-04 15:28:33 +00:00
|
|
|
await clipboardCopy(textToCopy);
|
2021-03-03 21:04:00 +00:00
|
|
|
|
|
|
|
return true;
|
2021-03-04 15:28:33 +00:00
|
|
|
} catch (e) {
|
|
|
|
return false;
|
2021-03-03 21:04:00 +00:00
|
|
|
}
|
2020-06-24 07:34:00 +00:00
|
|
|
}
|
|
|
|
|
2019-06-26 14:08:23 +00:00
|
|
|
/**
|
|
|
|
* Creates a deferred object.
|
|
|
|
*
|
|
|
|
* @returns {{promise, resolve, reject}}
|
|
|
|
*/
|
|
|
|
export function createDeferred(): Object {
|
2022-07-29 13:18:14 +00:00
|
|
|
const deferred: any = {};
|
2019-06-26 14:08:23 +00:00
|
|
|
|
|
|
|
deferred.promise = new Promise((resolve, reject) => {
|
|
|
|
deferred.resolve = resolve;
|
|
|
|
deferred.reject = reject;
|
|
|
|
});
|
|
|
|
|
|
|
|
return deferred;
|
|
|
|
}
|
|
|
|
|
2019-08-23 14:41:10 +00:00
|
|
|
const MATCH_OPERATOR_REGEXP = /[|\\{}()[\]^$+*?.-]/g;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Escape RegExp special characters.
|
|
|
|
*
|
|
|
|
* Based on https://github.com/sindresorhus/escape-string-regexp.
|
|
|
|
*
|
|
|
|
* @param {string} s - The regexp string to escape.
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
|
|
|
export function escapeRegexp(s: string) {
|
|
|
|
if (typeof s !== 'string') {
|
|
|
|
throw new TypeError('Expected a string');
|
|
|
|
}
|
|
|
|
|
|
|
|
return s.replace(MATCH_OPERATOR_REGEXP, '\\$&');
|
|
|
|
}
|
|
|
|
|
2019-07-03 15:39:39 +00:00
|
|
|
/**
|
|
|
|
* Returns the base URL of the app.
|
|
|
|
*
|
|
|
|
* @param {Object} w - Window object to use instead of the built in one.
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
2022-07-29 13:18:14 +00:00
|
|
|
export function getBaseUrl(w: Window = window) {
|
2019-07-03 15:39:39 +00:00
|
|
|
const doc = w.document;
|
|
|
|
const base = doc.querySelector('base');
|
|
|
|
|
|
|
|
if (base && base.href) {
|
|
|
|
return base.href;
|
|
|
|
}
|
|
|
|
|
|
|
|
const { protocol, host } = w.location;
|
|
|
|
|
|
|
|
return `${protocol}//${host}`;
|
|
|
|
}
|
|
|
|
|
2017-09-01 19:14:03 +00:00
|
|
|
/**
|
|
|
|
* Returns the namespace for all global variables, functions, etc that we need.
|
|
|
|
*
|
|
|
|
* @returns {Object} The namespace.
|
|
|
|
*
|
|
|
|
* NOTE: After React-ifying everything this should be the only global.
|
|
|
|
*/
|
|
|
|
export function getJitsiMeetGlobalNS() {
|
2022-07-29 13:18:14 +00:00
|
|
|
// @ts-ignore
|
2017-09-01 19:14:03 +00:00
|
|
|
if (!window.JitsiMeetJS) {
|
2022-07-29 13:18:14 +00:00
|
|
|
// @ts-ignore
|
2017-09-01 19:14:03 +00:00
|
|
|
window.JitsiMeetJS = {};
|
|
|
|
}
|
|
|
|
|
2022-07-29 13:18:14 +00:00
|
|
|
// @ts-ignore
|
2017-09-01 19:14:03 +00:00
|
|
|
if (!window.JitsiMeetJS.app) {
|
2022-07-29 13:18:14 +00:00
|
|
|
// @ts-ignore
|
2017-09-01 19:14:03 +00:00
|
|
|
window.JitsiMeetJS.app = {};
|
|
|
|
}
|
|
|
|
|
2022-07-29 13:18:14 +00:00
|
|
|
// @ts-ignore
|
2017-09-01 19:14:03 +00:00
|
|
|
return window.JitsiMeetJS.app;
|
|
|
|
}
|
2018-04-12 19:58:20 +00:00
|
|
|
|
2018-07-21 15:16:32 +00:00
|
|
|
/**
|
|
|
|
* Prints the error and reports it to the global error handler.
|
|
|
|
*
|
|
|
|
* @param {Error} e - The error object.
|
|
|
|
* @param {string} msg - A custom message to print in addition to the error.
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
2022-07-29 13:18:14 +00:00
|
|
|
export function reportError(e: Error, msg = '') {
|
2019-09-06 11:02:39 +00:00
|
|
|
console.error(msg, e);
|
2022-07-29 13:18:14 +00:00
|
|
|
window.onerror && window.onerror(msg, undefined, undefined, undefined, e);
|
2018-07-21 15:16:32 +00:00
|
|
|
}
|
2021-03-23 12:11:11 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds alpha to a color css string.
|
|
|
|
*
|
|
|
|
* @param {string} color - The color string either in rgb... Or #... Format.
|
|
|
|
* @param {number} opacity -The opacity(alpha) to apply to the color. Can take a value between 0 and 1, including.
|
|
|
|
* @returns {string} - The color with applied alpha.
|
|
|
|
*/
|
|
|
|
export function setColorAlpha(color: string, opacity: number) {
|
|
|
|
if (!color) {
|
|
|
|
return `rgba(0, 0, 0, ${opacity})`;
|
|
|
|
}
|
|
|
|
|
|
|
|
let b, g, r;
|
|
|
|
|
|
|
|
try {
|
|
|
|
if (color.startsWith('rgb')) {
|
|
|
|
[ r, g, b ] = color.split('(')[1].split(')')[0].split(',').map(c => c.trim());
|
|
|
|
} else if (color.startsWith('#')) {
|
|
|
|
if (color.length === 4) {
|
|
|
|
[ r, g, b ] = parseShorthandColor(color);
|
|
|
|
} else {
|
|
|
|
r = parseInt(color.substring(1, 3), 16);
|
|
|
|
g = parseInt(color.substring(3, 5), 16);
|
|
|
|
b = parseInt(color.substring(5, 7), 16);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return color;
|
|
|
|
}
|
|
|
|
|
|
|
|
return `rgba(${r}, ${g}, ${b}, ${opacity})`;
|
|
|
|
} catch {
|
|
|
|
return color;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the hexa rgb values for a shorthand css color.
|
|
|
|
*
|
|
|
|
* @param {string} color -
|
|
|
|
* @returns {Array<number>} - Array containing parsed r, g, b values of the color.
|
|
|
|
*/
|
2022-07-29 13:18:14 +00:00
|
|
|
function parseShorthandColor(color: string) {
|
2021-03-23 12:11:11 +00:00
|
|
|
let b, g, r;
|
|
|
|
|
|
|
|
r = color.substring(1, 2);
|
|
|
|
r += r;
|
|
|
|
r = parseInt(r, 16);
|
|
|
|
|
|
|
|
g = color.substring(2, 3);
|
|
|
|
g += g;
|
|
|
|
g = parseInt(g, 16);
|
|
|
|
|
|
|
|
b = color.substring(3, 4);
|
|
|
|
b += b;
|
|
|
|
b = parseInt(b, 16);
|
|
|
|
|
|
|
|
return [ r, g, b ];
|
|
|
|
}
|
2021-09-09 22:46:41 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Sorts an object by a sort function, same functionality as array.sort().
|
|
|
|
*
|
|
|
|
* @param {Object} object - The data object.
|
|
|
|
* @param {Function} callback - The sort function.
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
export function objectSort(object: Object, callback: Function) {
|
|
|
|
return Object.entries(object)
|
|
|
|
.sort(([ , a ], [ , b ]) => callback(a, b))
|
|
|
|
.reduce((row, [ key, value ]) => {
|
|
|
|
return { ...row,
|
|
|
|
[key]: value };
|
|
|
|
}, {});
|
|
|
|
}
|