@iobroker/adapter-react
Version:
React classes to develop admin interfaces for ioBroker with react.
1,683 lines (1,448 loc) • 54.8 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireDefault(require("react"));
var _i18n = _interopRequireDefault(require("../i18n"));
/**
* Copyright 2018-2022 bluefox <dogafox@gmail.com>
*
* MIT License
*
**/
var NAMESPACE = 'material';
var days = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
var QUALITY_BITS = {
0x00: '0x00 - good',
0x01: '0x01 - general problem',
0x02: '0x02 - no connection problem',
0x10: '0x10 - substitute value from controller',
0x20: '0x20 - substitute initial value',
0x40: '0x40 - substitute value from device or instance',
0x80: '0x80 - substitute value from sensor',
0x11: '0x11 - general problem by instance',
0x41: '0x41 - general problem by device',
0x81: '0x81 - general problem by sensor',
0x12: '0x12 - instance not connected',
0x42: '0x42 - device not connected',
0x82: '0x82 - sensor not connected',
0x44: '0x44 - device reports error',
0x84: '0x84 - sensor reports error'
};
var Utils = /*#__PURE__*/function () {
function Utils() {
(0, _classCallCheck2["default"])(this, Utils);
}
(0, _createClass2["default"])(Utils, null, [{
key: "CapitalWords",
value:
/**
* Capitalize words.
* @param {string | undefined} name
* @returns {string}
*/
function CapitalWords(name) {
return (name || '').split(/[\s_]/).filter(function (item) {
return item;
}).map(function (word) {
return word ? word[0].toUpperCase() + word.substring(1).toLowerCase() : '';
}).join(' ');
}
}, {
key: "formatSeconds",
value: function formatSeconds(seconds) {
var days = Math.floor(seconds / (3600 * 24));
seconds %= 3600 * 24;
var hours = Math.floor(seconds / 3600);
if (hours < 10) {
hours = '0' + hours;
}
seconds %= 3600;
var minutes = Math.floor(seconds / 60);
if (minutes < 10) {
minutes = '0' + minutes;
}
seconds %= 60;
seconds = Math.floor(seconds);
if (seconds < 10) {
seconds = '0' + seconds;
}
var text = '';
if (days) {
text += "".concat(days, " ").concat(_i18n["default"].t('ra_daysShortText'), " ");
}
text += "".concat(hours, ":").concat(minutes, ":").concat(seconds);
return text;
}
/**
* Get the name of the object by id from the name or description.
* @param {Record<string, ioBroker.Object>} objects
* @param {string} id
* @param {{ name: any; } | ioBroker.Languages | null} settings
* @param {{ language?: ioBroker.Languages; }} options
* @param {boolean} [isDesc] Set to true to get the description.
* @returns {string}
*/
}, {
key: "getObjectName",
value: function getObjectName(objects, id, settings, options, isDesc) {
var item = objects[id];
var text = id;
var attr = isDesc ? 'desc' : 'name';
if (typeof settings === 'string' && !options) {
options = {
language: settings
};
settings = null;
}
options = options || {};
if (!options.language) {
options.language = objects['system.config'] && objects['system.config'].common && objects['system.config'].common.language || window.sysLang || 'en';
}
if (settings && settings.name) {
text = settings.name;
if ((0, _typeof2["default"])(text) === 'object') {
text = text[options.language] || text.en;
}
} else if (item && item.common && item.common[attr]) {
text = item.common[attr];
if (attr !== 'desc' && !text && item.common.desc) {
text = item.common.desc;
}
if ((0, _typeof2["default"])(text) === 'object') {
text = text[options.language] || text.en || text.de || text.ru || '';
}
text = (text || '').toString().replace(/[_.]/g, ' ');
if (text === text.toUpperCase()) {
text = text[0] + text.substring(1).toLowerCase();
}
} else {
var pos = id.lastIndexOf('.');
text = id.substring(pos + 1).replace(/[_.]/g, ' ');
text = Utils.CapitalWords(text);
}
return text.trim();
}
/**
* Get the name of the object from the name or description.
* @param {ioBroker.PartialObject} obj
* @param {{ name: any; } | ioBroker.Languages | null } settings or language
* @param {{ language?: ioBroker.Languages; } } options
* @param {boolean} [isDesc] Set to true to get the description.
* @returns {string}
*/
}, {
key: "getObjectNameFromObj",
value: function getObjectNameFromObj(obj, settings, options, isDesc) {
var item = obj;
var text = obj && obj._id || '';
var attr = isDesc ? 'desc' : 'name';
if (typeof settings === 'string' && !options) {
options = {
language: settings
};
settings = null;
}
options = options || {};
if (settings && settings.name) {
text = settings.name;
if ((0, _typeof2["default"])(text) === 'object') {
text = text[options.language] || text.en;
}
} else if (item && item.common && item.common[attr]) {
text = item.common[attr];
if (attr !== 'desc' && !text && item.common.desc) {
text = item.common.desc;
}
if ((0, _typeof2["default"])(text) === 'object') {
text = text[options.language] || text.en;
}
text = (text || '').toString().replace(/[_.]/g, ' ');
if (text === text.toUpperCase()) {
text = text[0] + text.substring(1).toLowerCase();
}
}
return text.trim();
}
/**
* @param {ioBroker.PartialObject | ioBroker.ObjectCommon} obj
* @param {string} forEnumId
* @param {{ user: string; }} options
* @returns {string | null}
*/
}, {
key: "getSettingsOrder",
value: function getSettingsOrder(obj, forEnumId, options) {
if (obj && obj.hasOwnProperty('common')) {
obj = obj.common;
}
var settings;
if (obj && obj.custom) {
settings = (obj.custom || {})[NAMESPACE];
var user = options.user || 'admin';
if (settings && settings[user]) {
if (forEnumId) {
if (settings[user].subOrder && settings[user].subOrder[forEnumId]) {
return JSON.parse(JSON.stringify(settings[user].subOrder[forEnumId]));
}
} else {
if (settings[user].order) {
return JSON.parse(JSON.stringify(settings[user].order));
}
}
}
}
return null;
}
/**
* @param {ioBroker.PartialObject | ioBroker.ObjectCommon} obj
* @param {string} forEnumId
* @param {{ user: string; }} options
*/
}, {
key: "getSettingsCustomURLs",
value: function getSettingsCustomURLs(obj, forEnumId, options) {
if (obj && obj.hasOwnProperty('common')) {
obj = obj.common;
}
var settings;
if (obj && obj.custom) {
settings = (obj.custom || {})[NAMESPACE];
var user = options.user || 'admin';
if (settings && settings[user]) {
if (forEnumId) {
if (settings[user].subURLs && settings[user].subURLs[forEnumId]) {
return JSON.parse(JSON.stringify(settings[user].subURLs[forEnumId]));
}
} else {
if (settings[user].URLs) {
return JSON.parse(JSON.stringify(settings[user].URLs));
}
}
}
}
return null;
}
/**
* Reorder the array items in list between source and dest.
* @param {Iterable<any> | ArrayLike<any>} list
* @param {number} source
* @param {number} dest
*/
}, {
key: "reorder",
value: function reorder(list, source, dest) {
var result = Array.from(list);
var _result$splice = result.splice(source, 1),
_result$splice2 = (0, _slicedToArray2["default"])(_result$splice, 1),
removed = _result$splice2[0];
result.splice(dest, 0, removed);
return result;
}
}, {
key: "getSettings",
value:
/**
* @param {any} obj
* @param {{ id: any; user: any; name: any; icon: any; color: any; language: ioBroker.Languages; }} options
* @param {boolean} [defaultEnabling]
*/
function getSettings(obj, options, defaultEnabling) {
var settings;
var id = obj && obj._id || options && options.id;
if (obj && obj.hasOwnProperty('common')) {
obj = obj.common;
}
if (obj && obj.custom) {
settings = obj.custom || {};
settings = settings[NAMESPACE] && settings[NAMESPACE][options.user || 'admin'] ? JSON.parse(JSON.stringify(settings[NAMESPACE][options.user || 'admin'])) : {
enabled: true
};
} else {
settings = {
enabled: defaultEnabling === undefined ? true : defaultEnabling,
useCustom: false
};
}
if (!settings.hasOwnProperty('enabled')) {
settings.enabled = defaultEnabling === undefined ? true : defaultEnabling;
}
if (false && settings.useCommon) {
if (obj.color) settings.color = obj.color;
if (obj.icon) settings.icon = obj.icon;
if (obj.name) settings.name = obj.name;
} else {
if (options) {
if (!settings.name && options.name) settings.name = options.name;
if (!settings.icon && options.icon) settings.icon = options.icon;
if (!settings.color && options.color) settings.color = options.color;
}
if (obj) {
if (!settings.color && obj.color) settings.color = obj.color;
if (!settings.icon && obj.icon) settings.icon = obj.icon;
if (!settings.name && obj.name) settings.name = obj.name;
}
}
if ((0, _typeof2["default"])(settings.name) === 'object') {
settings.name = settings.name[options.language] || settings.name.en;
settings.name = (settings.name || '').toString().replace(/_/g, ' ');
if (settings.name === settings.name.toUpperCase()) {
settings.name = settings.name[0] + settings.name.substring(1).toLowerCase();
}
}
if (!settings.name && id) {
var pos = id.lastIndexOf('.');
settings.name = id.substring(pos + 1).replace(/[_.]/g, ' ');
settings.name = (settings.name || '').toString().replace(/_/g, ' ');
settings.name = Utils.CapitalWords(settings.name);
}
return settings;
}
/**
* @param {any} obj
* @param {any} settings
* @param {{ user: any; language: ioBroker.Languages; }} options
*/
}, {
key: "setSettings",
value: function setSettings(obj, settings, options) {
if (obj) {
obj.common = obj.common || {};
obj.common.custom = obj.common.custom || {};
obj.common.custom[NAMESPACE] = obj.common.custom[NAMESPACE] || {};
obj.common.custom[NAMESPACE][options.user || 'admin'] = settings;
var s = obj.common.custom[NAMESPACE][options.user || 'admin'];
if (s.useCommon) {
if (s.color !== undefined) {
obj.common.color = s.color;
delete s.color;
}
if (s.icon !== undefined) {
obj.common.icon = s.icon;
delete s.icon;
}
if (s.name !== undefined) {
if ((0, _typeof2["default"])(obj.common.name) !== 'object') {
obj.common.name = {};
obj.common.name[options.language] = s.name;
} else {
obj.common.name[options.language] = s.name;
}
delete s.name;
}
}
return true;
} else {
return false;
}
}
/**
* Get the icon for the given settings.
* @param {{ icon: string | undefined; name: string | undefined; prefix: string | undefined}} settings
* @param {any} style
* @returns {JSX.Element | null}
*/
}, {
key: "getIcon",
value: function getIcon(settings, style) {
if (settings && settings.icon) {
// If UTF-8 icon
if (settings.icon.length <= 2) {
return /*#__PURE__*/_react["default"].createElement("span", {
style: style || {}
}, settings.icon);
} else if (settings.icon.startsWith('data:image')) {
return /*#__PURE__*/_react["default"].createElement("img", {
alt: settings.name,
src: settings.icon,
style: style || {}
});
} else {
// may be later some changes for second type
return /*#__PURE__*/_react["default"].createElement("img", {
alt: settings.name,
src: (settings.prefix || '') + settings.icon,
style: style || {}
});
}
}
return null;
}
/**
* Get the icon for the given object.
* @param {string} id
* @param {{ common: { icon: any; }; }} obj
* @returns {string | null}
*/
}, {
key: "getObjectIcon",
value: function getObjectIcon(id, obj) {
// If id is Object
if ((0, _typeof2["default"])(id) === 'object') {
obj = id;
id = obj._id;
}
if (obj && obj.common && obj.common.icon) {
var icon = obj.common.icon; // If UTF-8 icon
if (typeof icon === 'string' && icon.length <= 2) {
return icon;
} else if (icon.startsWith('data:image')) {
return icon;
} else {
var parts = id.split('.');
if (parts[0] === 'system') {
icon = 'adapter/' + parts[2] + (icon.startsWith('/') ? '' : '/') + icon;
} else {
icon = 'adapter/' + parts[0] + (icon.startsWith('/') ? '' : '/') + icon;
}
if (window.location.pathname.match(/adapter\/[^/]+\/[^/]+\.html/)) {
icon = '../../' + icon;
} else if (window.location.pathname.match(/material\/[.\d]+/)) {
icon = '../../' + icon;
} else if (window.location.pathname.match(/material\//)) {
icon = '../' + icon;
}
return icon;
}
} else {
return null;
}
}
/**
* Splits CamelCase into words.
* @param {string | undefined} text
* @returns {string}
*/
}, {
key: "splitCamelCase",
value: function splitCamelCase(text) {
if (false && text !== text.toUpperCase()) {
var words = text.split(/\s+/);
for (var i = 0; i < words.length; i++) {
var word = words[i];
if (word.toLowerCase() !== word && word.toUpperCase() !== word) {
var z = 0;
var ww = [];
var start = 0;
while (z < word.length) {
if (word[z].match(/[A-ZÜÄÖА-Я]/)) {
ww.push(word.substring(start, z));
start = z;
}
z++;
}
if (start !== z) {
ww.push(word.substring(start, z));
}
for (var k = 0; k < ww.length; k++) {
words.splice(i + k, 0, ww[k]);
}
i += ww.length;
}
}
return words.map(function (w) {
w = w.trim();
if (w) {
return w[0].toUpperCase() + w.substring(1).toLowerCase();
}
return '';
}).join(' ');
} else {
return Utils.CapitalWords(text);
}
}
/**
* Check if the given color is bright.
* https://stackoverflow.com/questions/35969656/how-can-i-generate-the-opposite-color-according-to-current-color
* @param {string | null | undefined} color
* @param {boolean} [defaultValue]
* @returns {boolean}
*/
}, {
key: "isUseBright",
value: function isUseBright(color, defaultValue) {
if (color === null || color === undefined || color === '') {
return defaultValue === undefined ? true : defaultValue;
}
color = color.toString();
if (color.indexOf('#') === 0) {
color = color.slice(1);
}
var r;
var g;
var b;
var rgb = color.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
if (rgb && rgb.length === 4) {
r = parseInt(rgb[1], 10);
g = parseInt(rgb[2], 10);
b = parseInt(rgb[3], 10);
} else {
// convert 3-digit hex to 6-digits.
if (color.length === 3) {
color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2];
}
if (color.length !== 6) {
return false;
}
r = parseInt(color.slice(0, 2), 16);
g = parseInt(color.slice(2, 4), 16);
b = parseInt(color.slice(4, 6), 16);
} // http://stackoverflow.com/a/3943023/112731
return r * 0.299 + g * 0.587 + b * 0.114 <= 186;
}
}, {
key: "getTimeString",
value:
/**
* Get the time string in the format 00:00.
* @param {string | number} seconds
*/
function getTimeString(seconds) {
seconds = parseFloat(seconds);
if (isNaN(seconds)) {
return '--:--';
}
var hours = Math.floor(seconds / 3600);
var minutes = Math.floor(seconds % 3600 / 60);
var secs = seconds % 60;
if (hours) {
if (minutes < 10) minutes = '0' + minutes;
if (secs < 10) secs = '0' + secs;
return hours + ':' + minutes + ':' + secs;
} else {
if (secs < 10) secs = '0' + secs;
return minutes + ':' + secs;
}
}
/**
* Gets the wind direction with the given angle (degrees).
* @param {number} angle in degrees.
* @returns {string | undefined}
*/
}, {
key: "getWindDirection",
value: function getWindDirection(angle) {
if (angle >= 0 && angle < 11.25) {
return 'N';
} else if (angle >= 11.25 && angle < 33.75) {
return 'NNE';
} else if (angle >= 33.75 && angle < 56.25) {
return 'NE';
} else if (angle >= 56.25 && angle < 78.75) {
return 'ENE';
} else if (angle >= 78.75 && angle < 101.25) {
return 'E';
} else if (angle >= 101.25 && angle < 123.75) {
return 'ESE';
} else if (angle >= 123.75 && angle < 146.25) {
return 'SE';
} else if (angle >= 146.25 && angle < 168.75) {
return 'SSE';
} else if (angle >= 168.75 && angle < 191.25) {
return 'S';
} else if (angle >= 191.25 && angle < 213.75) {
return 'SSW';
} else if (angle >= 213.75 && angle < 236.25) {
return 'SW';
} else if (angle >= 236.25 && angle < 258.75) {
return 'WSW';
} else if (angle >= 258.75 && angle < 281.25) {
return 'W';
} else if (angle >= 281.25 && angle < 303.75) {
return 'WNW';
} else if (angle >= 303.75 && angle < 326.25) {
return 'NW';
} else if (angle >= 326.25 && angle < 348.75) {
return 'NNW';
} else if (angle >= 348.75) {
return 'N';
}
}
/**
* Pad the given number with a zero if its not 2 digits long.
* @param {string | number} num
*/
}, {
key: "padding",
value: function padding(num) {
if (typeof num === 'string') {
if (num.length < 2) {
return '0' + num;
} else {
return num;
}
} else if (num < 10) {
return '0' + num;
} else {
return num;
}
}
/**
* Sets the date format.
* @param {string} format
*/
}, {
key: "setDataFormat",
value: function setDataFormat(format) {
if (format) {
Utils.dateFormat = format.toUpperCase().split(/[.-/]/);
Utils.dateFormat.splice(Utils.dateFormat.indexOf('YYYY'), 1);
}
}
/**
* Converts the date to a string.
* @param {string | number | Date} now
* @returns {string}
*/
}, {
key: "date2string",
value: function date2string(now) {
if (typeof now === 'string') {
now = now.trim();
if (!now) return ''; // only letters
if (now.match(/^[\w\s]+$/)) {
// Day of week
return now;
}
var m = now.match(/(\d{1,4})[-./](\d{1,2})[-./](\d{1,4})/);
if (m) {
var a = [parseInt(m[1], 10), parseInt(m[2], 10), parseInt(m[3], 10)];
var year = a.find(function (y) {
return y > 31;
});
a.splice(a.indexOf(year), 1);
var day = a.find(function (m) {
return m > 12;
});
if (day) {
a.splice(a.indexOf(day), 1);
now = new Date(year, a[0] - 1, day);
} else {
// MM DD
if (Utils.dateFormat[0][0] === 'M' && Utils.dateFormat[1][0] === 'D') {
now = new Date(year, a[0] - 1, a[1]);
if (Math.abs(now.getTime - Date.now()) > 3600000 * 24 * 10) {
now = new Date(year, a[1] - 1, a[0]);
}
} else // DD MM
if (Utils.dateFormat[0][0] === 'D' && Utils.dateFormat[1][0] === 'M') {
now = new Date(year, a[1] - 1, a[0]);
if (Math.abs(now.getTime - Date.now()) > 3600000 * 24 * 10) {
now = new Date(year, a[0] - 1, a[1]);
}
} else {
now = new Date(now);
}
}
} else {
now = new Date(now);
}
} else {
now = new Date(now);
}
var date = _i18n["default"].t('ra_dow_' + days[now.getDay()]).replace('ra_dow_', '');
date += '. ' + now.getDate() + ' ' + _i18n["default"].t('ra_month_' + months[now.getMonth()]).replace('ra_month_', '');
return date;
}
/**
* Render a text as a link.
* @param {string} text
* @returns {string | JSX.Element[]}
*/
}, {
key: "renderTextWithA",
value: function renderTextWithA(text) {
var m = text.match(/<a [^<]+<\/a>|<br\/?>/);
if (m) {
var result = [];
var key = 1;
do {
var p = text.split(m[0]);
p[0] && result.push( /*#__PURE__*/_react["default"].createElement("span", {
key: 'a' + key++
}, p[0]));
if (m[0].startsWith('<br')) {
result.push( /*#__PURE__*/_react["default"].createElement("br", {
key: 'a' + key++
}));
} else {
var href = m[0].match(/href="([^"]+)"/) || m[0].match(/href='([^']+)'/);
var target = m[0].match(/target="([^"]+)"/) || m[0].match(/target='([^']+)'/);
var rel = m[0].match(/rel="([^"]+)"/) || m[0].match(/rel='([^']+)'/);
var title = m[0].match(/>([^<]*)</); // eslint-disable-next-line
result.push( /*#__PURE__*/_react["default"].createElement("a", {
key: 'a' + key++,
href: href ? href[1] : '',
target: target ? target[1] : '_blank',
rel: rel ? rel[1] : ''
}, title ? title[1] : ''));
}
text = p[1];
m = text && text.match(/<a [^<]+<\/a>|<br\/?>/);
if (!m) {
p[1] && result.push( /*#__PURE__*/_react["default"].createElement("span", {
key: 'a' + key++
}, p[1]));
}
} while (m);
return result;
} else {
return text;
}
}
/**
* Get the smart name of the given state.
* @param {Record<string, ioBroker.StateObject> | ioBroker.StateObject} states
* @param {string} id
* @param {string} instanceId
* @param {boolean} [noCommon]
*/
}, {
key: "getSmartName",
value: function getSmartName(states, id, instanceId, noCommon) {
if (!id) {
if (!noCommon) {
if (!states.common) {
return states.smartName;
} else {
if (states && !states.common) {
return states.smartName;
} else {
return states.common.smartName;
}
}
} else {
if (states && !states.common) {
return states.smartName;
} else {
return states && states.common && states.common.custom && states.common.custom[instanceId] ? states.common.custom[instanceId].smartName : undefined;
}
}
} else if (!noCommon) {
return states[id].common.smartName;
} else {
return states[id] && states[id].common && states[id].common.custom && states[id].common.custom[instanceId] ? states[id].common.custom[instanceId].smartName || null : null;
}
}
/**
* Get the smart name from a state.
* @param {ioBroker.StateObject} obj
* @param {string} instanceId
* @param {boolean} [noCommon]
*/
}, {
key: "getSmartNameFromObj",
value: function getSmartNameFromObj(obj, instanceId, noCommon) {
if (!noCommon) {
if (!obj.common) {
return obj.smartName;
} else {
if (obj && !obj.common) {
return obj.smartName;
} else {
return obj.common.smartName;
}
}
} else {
if (obj && !obj.common) {
return obj.smartName;
} else {
return obj && obj.common && obj.common.custom && obj.common.custom[instanceId] ? obj.common.custom[instanceId].smartName : undefined;
}
}
}
/**
* Enable smart name for a state.
* @param {ioBroker.StateObject} obj
* @param {string} instanceId
* @param {boolean} [noCommon]
*/
}, {
key: "enableSmartName",
value: function enableSmartName(obj, instanceId, noCommon) {
if (noCommon) {
obj.common.custom = obj.common.custom || {};
obj.common.custom[instanceId] = obj.common.custom[instanceId] || {};
obj.common.custom[instanceId].smartName = {};
} else {
obj.common.smartName = {};
}
}
/**
* Completely remove smart name from a state.
* @param {ioBroker.StateObject} obj
* @param {string | number} instanceId
* @param {boolean} [noCommon]
*/
}, {
key: "removeSmartName",
value: function removeSmartName(obj, instanceId, noCommon) {
if (noCommon) {
if (obj.common && obj.common.custom && obj.common.custom[instanceId]) {
obj.common.custom[instanceId] = null;
}
} else {
obj.common.smartName = null;
}
}
/**
* Update the smartname of a state.
* @param {ioBroker.StateObject} obj
* @param {string} newSmartName
* @param {string | undefined} byON
* @param {string | undefined} smartType
* @param {string} instanceId
* @param {boolean} [noCommon]
*/
}, {
key: "updateSmartName",
value: function updateSmartName(obj, newSmartName, byON, smartType, instanceId, noCommon) {
var language = _i18n["default"].getLanguage(); // convert Old format
if (typeof obj.common.smartName === 'string') {
var nnn = obj.common.smartName;
obj.common.smartName = {};
obj.common.smartName[language] = nnn;
} // convert old settings
if (obj["native"] && obj["native"].byON) {
delete obj["native"].byON;
var _smartName = obj.common.smartName;
if (!_smartName || (0, _typeof2["default"])(_smartName) !== 'object') {
_smartName = {
en: _smartName
};
_smartName[language] = _smartName.en;
}
obj.common.smartName = _smartName;
}
if (smartType !== undefined) {
if (noCommon) {
obj.common.custom = obj.common.custom || {};
obj.common.custom[instanceId] = obj.common.custom[instanceId] || {};
obj.common.custom[instanceId].smartName = obj.common.custom[instanceId].smartName || {};
if (!smartType) {
delete obj.common.custom[instanceId].smartName.smartType;
} else {
obj.common.custom[instanceId].smartName.smartType = smartType;
}
} else {
obj.common.smartName = obj.common.smartName || {};
if (!smartType) {
delete obj.common.smartName.smartType;
} else {
obj.common.smartName.smartType = smartType;
}
}
}
if (byON !== undefined) {
if (noCommon) {
obj.common.custom = obj.common.custom || {};
obj.common.custom[instanceId] = obj.common.custom[instanceId] || {};
obj.common.custom[instanceId].smartName = obj.common.custom[instanceId].smartName || {};
obj.common.custom[instanceId].smartName.byON = byON;
} else {
obj.common.smartName = obj.common.smartName || {};
obj.common.smartName.byON = byON;
}
}
if (newSmartName !== undefined) {
var smartName;
if (noCommon) {
obj.common.custom = obj.common.custom || {};
obj.common.custom[instanceId] = obj.common.custom[instanceId] || {};
obj.common.custom[instanceId].smartName = obj.common.custom[instanceId].smartName || {};
smartName = obj.common.custom[instanceId].smartName;
} else {
obj.common.smartName = obj.common.smartName || {};
smartName = obj.common.smartName;
}
smartName[language] = newSmartName; // If smart name deleted
if (smartName && (!smartName[language] || smartName[language] === obj.common.name && (!obj.common.role || obj.common.role.indexOf('button') >= 0))) {
delete smartName[language];
var empty = true; // Check if structure has any definitions
for (var key in smartName) {
if (smartName.hasOwnProperty(key)) {
empty = false;
break;
}
} // If empty => delete smartName completely
if (empty) {
if (noCommon) {
if (obj.common.custom[instanceId].smartName.byON === undefined) {
delete obj.common.custom[instanceId];
} else {
delete obj.common.custom[instanceId].en;
delete obj.common.custom[instanceId].de;
delete obj.common.custom[instanceId].ru;
delete obj.common.custom[instanceId].nl;
delete obj.common.custom[instanceId].pl;
delete obj.common.custom[instanceId].it;
delete obj.common.custom[instanceId].fr;
delete obj.common.custom[instanceId].pt;
delete obj.common.custom[instanceId].es;
delete obj.common.custom[instanceId]['zh-cn'];
}
} else {
if (obj.common.smartName.byON !== undefined) {
delete obj.common.smartName.en;
delete obj.common.smartName.de;
delete obj.common.smartName.ru;
delete obj.common.smartName.nl;
delete obj.common.smartName.pl;
delete obj.common.smartName.it;
delete obj.common.smartName.fr;
delete obj.common.smartName.pt;
delete obj.common.smartName.es;
delete obj.common.smartName['zh-cn'];
} else {
obj.common.smartName = null;
}
}
}
}
}
}
/**
* Disable the smart name of a state.
* @param {ioBroker.StateObject} obj
* @param {string} instanceId
* @param {boolean} [noCommon]
*/
}, {
key: "disableSmartName",
value: function disableSmartName(obj, instanceId, noCommon) {
if (noCommon) {
obj.common.custom = obj.common.custom || {};
obj.common.custom[instanceId] = obj.common.custom[instanceId] || {};
obj.common.custom[instanceId].smartName = false;
} else {
obj.common.smartName = false;
}
}
/**
* Copy text to the clipboard.
* @param {string} text
* @param {Event} [e]
*/
}, {
key: "copyToClipboard",
value: function copyToClipboard(text, e) {
var el = window.document.createElement('textarea');
el.value = text;
window.document.body.appendChild(el);
el.select();
window.document.execCommand('copy');
window.document.body.removeChild(el);
console.log(text);
e && e.stopPropagation();
e && e.preventDefault();
}
/**
* Gets the extension of a file name.
* @param {string | null} [fileName] the file name.
* @returns {string | null} The extension in lower case.
*/
}, {
key: "getFileExtension",
value: function getFileExtension(fileName) {
var pos = (fileName || '').lastIndexOf('.');
if (pos !== -1) {
return fileName.substring(pos + 1).toLowerCase();
} else {
return null;
}
}
/**
* Format number of bytes as a string with B, KB, MB or GB.
* The base for all calculations is 1024.
* @param {number} bytes The number of bytes.
* @returns {string} The formatted string (e.g. '723.5 KB')
*/
}, {
key: "formatBytes",
value: function formatBytes(bytes) {
if (Math.abs(bytes) < 1024) {
return bytes + ' B';
}
var units = ['KB', 'MB', 'GB']; //const units = ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];
var u = -1;
do {
bytes /= 1024;
++u;
} while (Math.abs(bytes) >= 1024 && u < units.length - 1);
return bytes.toFixed(1) + ' ' + units[u];
}
/**
* Invert the given color according to theme type to get the inverted text color for background
* @param {string} color Color in the format '#rrggbb' or '#rgb' (or without hash)
* @param {string} themeType theme type
* @param {string} invert dark theme has light color in control or light theme has light color in control
* @returns {string}
*/
}, {
key: "getInvertedColor",
value: function getInvertedColor(color, themeType, invert) {
if (!color) {
return undefined;
} else {
var invertedColor = Utils.invertColor(color, true);
if (invertedColor === '#FFFFFF' && (themeType === 'dark' || invert && themeType === 'light')) {
return '#DDD';
} else if (invertedColor === '#000000' && (themeType === 'light' || invert && themeType === 'dark')) {
return '#222';
} else {
return undefined;
}
}
} // Big thanks to: https://stackoverflow.com/questions/35969656/how-can-i-generate-the-opposite-color-according-to-current-color
/**
* Invert the given color
* @param {string} hex Color in the format '#rrggbb' or '#rgb' (or without hash)
* @param {boolean} bw Set to black or white.
* @returns {string}
*/
}, {
key: "invertColor",
value: function invertColor(hex, bw) {
if (hex === undefined || hex === null || hex === '' || typeof hex !== 'string') {
return '';
}
if (hex.startsWith('rgba')) {
var m = hex.match(/rgba?\((\d+),\s*(\d+),\s*(\d+),\s*([.\d]+)\)/);
if (m) {
hex = parseInt(m[1], 10).toString(16).padStart(2, '0') + parseInt(m[2], 10).toString(16).padStart(2, '0') + parseInt(m[2], 10).toString(16).padStart(2, '0');
}
} else if (hex.startsWith('rgba')) {
var _m = hex.match(/rgb?\((\d+),\s*(\d+),\s*(\d+)\)/);
if (_m) {
hex = parseInt(_m[1], 10).toString(16).padStart(2, '0') + parseInt(_m[2], 10).toString(16).padStart(2, '0') + parseInt(_m[2], 10).toString(16).padStart(2, '0');
}
} else if (hex.startsWith('#')) {
hex = hex.slice(1);
} // convert 3-digit hex to 6-digits.
if (hex.length === 3) {
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
}
if (hex.length !== 6) {
console.warn('Cannot invert color: ' + hex);
return hex;
}
var r = parseInt(hex.slice(0, 2), 16);
var g = parseInt(hex.slice(2, 4), 16);
var b = parseInt(hex.slice(4, 6), 16);
if (bw) {
// http://stackoverflow.com/a/3943023/112731
return r * 0.299 + g * 0.587 + b * 0.114 > 186 ? '#000000' : '#FFFFFF';
} // invert color components
r = (255 - r).toString(16);
g = (255 - g).toString(16);
b = (255 - b).toString(16); // pad each with zeros and return
return '#' + r.padStart(2, '0') + g.padStart(2, '0') + b.padStart(2, '0');
} // https://github.com/lukeed/clsx/blob/master/src/index.js
// License
// MIT © Luke Edwards
/**
* @private
* @param {any} mix
* @returns {string}
*/
}, {
key: "_toVal",
value: function _toVal(mix) {
var k,
y,
str = '';
if (typeof mix === 'string' || typeof mix === 'number') {
str += mix;
} else if ((0, _typeof2["default"])(mix) === 'object') {
if (Array.isArray(mix)) {
for (k = 0; k < mix.length; k++) {
if (mix[k]) {
if (y = Utils._toVal(mix[k])) {
str && (str += ' ');
str += y;
}
}
}
} else {
for (k in mix) {
if (mix[k]) {
str && (str += ' ');
str += k;
}
}
}
}
return str;
} // https://github.com/lukeed/clsx/blob/master/src/index.js
// License
// MIT © Luke Edwards
/**
* Convert any object to a string with its values.
* @returns {string}
*/
}, {
key: "clsx",
value: function clsx() {
var i = 0;
var tmp;
var x;
var str = '';
while (i < arguments.length) {
if (tmp = arguments[i++]) {
if (x = Utils._toVal(tmp)) {
str && (str += ' ');
str += x;
}
}
}
return str;
}
/**
* Get the current theme name (either from local storage or the browser settings).
* @param {string} [themeName]
* @returns {string}
*/
}, {
key: "getThemeName",
value: function getThemeName() {
var themeName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
if (window.vendorPrefix && window.vendorPrefix !== '@@vendorPrefix@@') {
return window.vendorPrefix;
}
return themeName ? themeName : window.localStorage && window.localStorage.getItem('App.themeName') ? window.localStorage.getItem('App.themeName') : window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'colored';
}
/**
* Get the type of theme.
* @param {string} [themeName]
* @returns {'dark' | 'light'}
*/
}, {
key: "getThemeType",
value: function getThemeType() {
var themeName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
if (window.vendorPrefix && window.vendorPrefix !== '@@vendorPrefix@@') {
return 'light';
}
themeName = themeName || window.localStorage && window.localStorage.getItem('App.themeName');
return themeName === 'dark' || themeName === 'blue' ? 'dark' : 'light';
}
/**
* Set the theme name and theme type.
* @param {string} themeName
*/
}, {
key: "setThemeName",
value: function setThemeName(themeName) {
if (window.vendorPrefix && window.vendorPrefix !== '@@vendorPrefix@@') {
return; // ignore
}
window.localStorage.setItem('App.themeName', themeName);
window.localStorage.setItem('App.theme', themeName === 'dark' || themeName === 'blue' ? 'dark' : 'light');
}
/**
* Toggle the theme name between 'dark' and 'colored'.
* @param {string | null} themeName
* @returns {string} the new theme name.
*/
}, {
key: "toggleTheme",
value: function toggleTheme(themeName) {
if (window.vendorPrefix && window.vendorPrefix !== '@@vendorPrefix@@') {
return window.vendorPrefix;
}
themeName = themeName || window.localStorage && window.localStorage.getItem('App.themeName'); // dark => blue => colored => light => dark
var themes = Utils.getThemeNames();
var pos = themes.indexOf(themeName);
var newTheme;
if (pos !== -1) {
newTheme = themes[(pos + 1) % themes.length];
} else {
newTheme = themes[0];
}
Utils.setThemeName(newTheme);
return newTheme;
}
/**
* Get the list of themes
* @returns {array<string>} list of possible themes
*/
}, {
key: "getThemeNames",
value: function getThemeNames() {
if (window.vendorPrefix && window.vendorPrefix !== '@@vendorPrefix@@') {
return [window.vendorPrefix];
}
return ['light', 'dark', 'blue', 'colored'];
}
/**
* Parse a query string into its parts.
* @param {string} query
* @returns {Record<string, string | boolean | number>}
*/
}, {
key: "parseQuery",
value: function parseQuery(query) {
query = (query || '').toString().replace(/^\?/, '');
/** @type {Record<string, string | boolean | number>} */
var result = {};
query.split('&').forEach(function (part) {
part = part.trim();
if (part) {
var parts = part.split('=');
var attr = decodeURIComponent(parts[0]).trim();
if (parts.length > 1) {
result[attr] = decodeURIComponent(parts[1]);
if (result[attr] === 'true') {
result[attr] = true;
} else if (result[attr] === 'false') {
result[attr] = false;
} else {
var f = parseFloat(result[attr]);
if (f.toString() === result[attr]) {
result[attr] = f;
}
}
} else {
result[attr] = true;
}
}
});
return result;
}
/**
* Returns parent ID.
* @param {string} id
* @returns {string | null} parent ID or null if no parent
*/
}, {
key: "getParentId",
value: function getParentId(id) {
var p = (id || '').toString().split('.');
if (p.length > 1) {
p.pop();
return p.join('.');
} else {
return null;
}
}
}, {
key: "formatDate",
value: function formatDate(dateObj, dateFormat) {
// format could be DD.MM.YYYY, YYYY.MM.DD or MM/DD/YYYY
if (!dateObj) {
return '';
}
var text;
var mm = dateObj.getMonth() + 1;
if (mm < 10) {
mm = '0' + mm;
}
var dd = dateObj.getDate();
if (dd < 10) {
dd = '0' + dd;
}
if (dateFormat === 'MM/DD/YYYY') {
text = mm + '/' + dd + '/' + dateObj.getFullYear();
} else {
text = dateObj.getFullYear() + '-' + mm + '-' + dd;
} // time
var v = dateObj.getHours();
if (v < 10) {
text += ' 0' + v;
} else {
text += ' ' + v;
}
v = dateObj.getMinutes();
if (v < 10) {
text += ':0' + v;
} else {
text += ':' + v;
}
v = dateObj.getSeconds();
if (v < 10) {
text += ':0' + v;
} else {
text += ':' + v;
}
v = dateObj.getMilliseconds();
if (v < 10) {
text += '.00' + v;
} else if (v < 100) {
text += '.0' + v;
} else {
text += '.' + v;
}
return text;
}
}, {
key: "formatTime",
value: function formatTime(seconds) {
if (seconds) {
seconds = Math.round(seconds);
var d = Math.floor(seconds / (3600 * 24));
var h = Math.floor(seconds % (3600 * 24) / 3600);
var m = Math.floor(seconds % 3600 / 60);
var s = seconds % 60;
if (d) {
return "".concat(d, ".").concat(h.toString().padStart(2, '0'), ":").concat(m.toString().padStart(2, '0'), ":").concat(s.toString().padStart(2, '0'));
} else if (h) {
return "".concat(h, ":").concat(m.toString().padStart(2, '0'), ":").concat(s.toString().padStart(2, '0'));
} else {
return "0:".concat(m.toString().padStart(2, '0'), ":").concat(s.toString().padStart(2, '0'));
}
} else {
return '0:00:00';
}
}
}, {
key: "MDtext2link",
value: function MDtext2link(text) {
var m = text.match(/\d+\.\)\s/);
if (m) {
text = text.replace(m[0], m[0].replace(/\s/, ' '));
}
return text.replace(/[^a-zA-Zа-яА-Я0-9]/g, '').trim().replace(/\s/g, '').toLowerCase();
}
}, {
key: "openLink",
value: function openLink(url, target) {
// replace IPv6 Address with [ipv6]:port
url = url.replace(/\/\/([0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*)(:\d+)?\//i, '//[$1]$2/');
if (target === 'this') {
window.location = url;
} else {
window.open(url, target || '_blank');
}
}
}, {
key: "MDgetTitle",
value: function MDgetTitle(text) {
var _Utils$extractHeader = Utils.extractHeader(text),
body = _Utils$extractHeader.body,
header = _Utils$extractHeader.header;
if (!header.title) {
// remove {docsify-bla}
body = body.replace(/{[^}]*}/g, '');
body = body.trim();
var lines = body.replace(/\r/g, '').split('\n');
for (var i = 0; i < lines.length; i++) {
if (lines[i].startsWith('# ')) {
return lines[i].substring(2).trim();
}
}
return '';
} else {
return header.title;
}
}
}, {
key: "MDextractHeader",
value: function MDextractHeader(text) {
var attrs = {};
if (text.substring(0, 3) === '---') {
var pos = text.substring(3).indexOf('\n---');
if (pos !== -1) {
var _header = text.substring(3, pos + 3);
var lines = _header.replace(/\r/g, '').split('\n');
lines.forEach(function (line) {
if (!line.trim()) {
return;
}
var pos = line.indexOf(':');
if (pos !== -1) {
var attr = line.substring(0, pos).trim();
attrs[attr] = line.substring(pos + 1).trim();
attrs[attr] = attrs[attr].replace(/^['"]|['"]$/g, '');
if (attrs[attr] === 'true') {
attrs[attr] = true;
} else if (attrs[attr] === 'false') {
attrs[attr] = false;
} else if (parseFloat(attrs[attr]).toString() === attrs[attr]) {
attrs[attr] = parseFloat(attrs[attr]);
}
} else {
attrs[line.trim()] = true;
}
});
text = text.substring(pos + 7);
}
}
return {
header: attrs,
body: text
};
}
}, {
key: "MDremoveDocsify",
value: function MDremoveDocsify(text) {
var m = text.match(/{docsify-[^}]*}/g);
if (m) {
m.forEach(function (doc) {
return text = text.replace(doc, '');
});
}
return text;
}
/**
* Generate the json file on the file for download.
* @param {string} filename file name
* @returns {object} json structure (not stringified)
*/
}, {
key: "generateFile",
value: function generateFile(filename, json) {
var el = document.createElement('a');
el.setAttribute('href', 'data:application/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(json, null, 2)));
el.setAttribute('download', filename);
el.style.display = 'none';
document.body.appendChild(el);
el.click();
document.body.removeChild(el);
}
/**
* Convert quality code into text
* @param {number} quality code
* @returns {array<string>} lines that decode qulity
*/
}, {
key: "quality2text",
value: function quality2text(quality) {
var custom = quality & 0xFFFF0000;
var text = QUALITY_BITS[quality];
var result;
if (text) {
result = [text];
} else if (quality & 0x01) {
result = [QUALITY_BITS[0x01], '0x' + (quality & (0xFFFF & ~1)).toString(16)];
} else if (quality & 0x02) {
result = [QUALITY_BITS[0x02], '0x' + (quality & (0xFFFF & ~2)).toString(16)];
} else {
result = ['0x' + quality.toString(16)];
}
if (custom) {
result.push('0x' + (custom >> 16).toString(16).toUpperCase());
}
return result;
}
/**
* Deep copy object
* @param {object} object
* @returns {object}
*/
}, {
key: "clone",
value: function clone(object) {
return JSON.parse(JSON.stringify(object));
}
/**
* Get states of object
* @param {object} obj
* @returns {object} states as an object in form {"value1