utils.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. import _ from 'lodash';
  2. import baseX from 'base-x';
  3. import PAKO from 'pako';
  4. import {Buffer} from 'safe-buffer';
  5. import sjclWrapper from './sjclWrapper';
  6. export const pako = PAKO;
  7. const BASE58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
  8. const bs58 = baseX(BASE58);
  9. export function sleep(ms) {
  10. return new Promise(resolve => setTimeout(resolve, ms));
  11. }
  12. export function stringToHex(str) {
  13. return Buffer.from(str).toString('hex');
  14. }
  15. export function hexToString(str) {
  16. return Buffer.from(str, 'hex').toString();
  17. }
  18. export function randomArray(len) {
  19. const a = new Uint8Array(len);
  20. window.crypto.getRandomValues(a);
  21. return a;
  22. }
  23. export function randomHexString(len) {
  24. return Buffer.from(randomArray(len)).toString('hex');
  25. }
  26. export function formatDate(d, format) {
  27. if (!format)
  28. format = 'normal';
  29. switch (format) {
  30. case 'normal':
  31. return `${d.getDate().toString().padStart(2, '0')}.${(d.getMonth() + 1).toString().padStart(2, '0')}.${d.getFullYear()} ` +
  32. `${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}`;
  33. case 'coDate':
  34. return `${d.getFullYear()}-${(d.getMonth() + 1).toString().padStart(2, '0')}-${d.getDate().toString().padStart(2, '0')}`;
  35. case 'noDate':
  36. return `${d.getDate().toString().padStart(2, '0')}.${(d.getMonth() + 1).toString().padStart(2, '0')}.${d.getFullYear()}`;
  37. }
  38. }
  39. export function fallbackCopyTextToClipboard(text) {
  40. let textArea = document.createElement('textarea');
  41. textArea.value = text;
  42. document.body.appendChild(textArea);
  43. textArea.focus();
  44. textArea.select();
  45. let result = false;
  46. try {
  47. result = document.execCommand('copy');
  48. } catch (e) {
  49. //
  50. }
  51. document.body.removeChild(textArea);
  52. return result;
  53. }
  54. export async function copyTextToClipboard(text) {
  55. if (!navigator.clipboard) {
  56. return fallbackCopyTextToClipboard(text);
  57. }
  58. let result = false;
  59. try {
  60. await navigator.clipboard.writeText(text);
  61. result = true;
  62. } catch (e) {
  63. //
  64. }
  65. return result;
  66. }
  67. export function toBase58(data) {
  68. return bs58.encode(Buffer.from(data));
  69. }
  70. export function fromBase58(data) {
  71. return bs58.decode(data);
  72. }
  73. //base-x слишком тормозит, используем sjcl
  74. export function toBase64(data) {
  75. return sjclWrapper.codec.base64.fromBits(
  76. sjclWrapper.codec.bytes.toBits(Buffer.from(data))
  77. );
  78. }
  79. //base-x слишком тормозит, используем sjcl
  80. export function fromBase64(data) {
  81. return Buffer.from(sjclWrapper.codec.bytes.fromBits(
  82. sjclWrapper.codec.base64.toBits(data)
  83. ));
  84. }
  85. export function getObjDiff(oldObj, newObj) {
  86. const result = {__isDiff: true, change: {}, add: {}, del: []};
  87. for (const key of Object.keys(oldObj)) {
  88. if (newObj.hasOwnProperty(key)) {
  89. if (!_.isEqual(oldObj[key], newObj[key])) {
  90. if (_.isObject(oldObj[key]) && _.isObject(newObj[key])) {
  91. result.change[key] = getObjDiff(oldObj[key], newObj[key]);
  92. } else {
  93. result.change[key] = _.cloneDeep(newObj[key]);
  94. }
  95. }
  96. } else {
  97. result.del.push(key);
  98. }
  99. }
  100. for (const key of Object.keys(newObj)) {
  101. if (!oldObj.hasOwnProperty(key)) {
  102. result.add[key] = _.cloneDeep(newObj[key]);
  103. }
  104. }
  105. return result;
  106. }
  107. export function isObjDiff(diff) {
  108. return (_.isObject(diff) && diff.__isDiff && diff.change && diff.add && diff.del);
  109. }
  110. export function isEmptyObjDiff(diff) {
  111. return (!isObjDiff(diff) ||
  112. !(Object.keys(diff.change).length ||
  113. Object.keys(diff.add).length ||
  114. diff.del.length
  115. )
  116. );
  117. }
  118. export function isEmptyObjDiffDeep(diff, opts = {}) {
  119. if (!isObjDiff(diff))
  120. return true;
  121. const {
  122. isApplyChange = true,
  123. isApplyAdd = true,
  124. isApplyDel = true,
  125. } = opts;
  126. let notEmptyDeep = false;
  127. const change = diff.change;
  128. for (const key of Object.keys(change)) {
  129. if (_.isObject(change[key]))
  130. notEmptyDeep |= !isEmptyObjDiffDeep(change[key], opts);
  131. else if (isApplyChange)
  132. notEmptyDeep = true;
  133. }
  134. return !(
  135. notEmptyDeep ||
  136. (isApplyAdd && Object.keys(diff.add).length) ||
  137. (isApplyDel && diff.del.length)
  138. );
  139. }
  140. export function applyObjDiff(obj, diff, opts = {}) {
  141. const {
  142. isAddChanged = false,
  143. isApplyChange = true,
  144. isApplyAdd = true,
  145. isApplyDel = true,
  146. } = opts;
  147. let result = _.cloneDeep(obj);
  148. if (!diff.__isDiff)
  149. return result;
  150. const change = diff.change;
  151. for (const key of Object.keys(change)) {
  152. if (result.hasOwnProperty(key)) {
  153. if (_.isObject(change[key])) {
  154. result[key] = applyObjDiff(result[key], change[key], opts);
  155. } else {
  156. if (isApplyChange)
  157. result[key] = _.cloneDeep(change[key]);
  158. }
  159. } else if (isAddChanged) {
  160. result[key] = _.cloneDeep(change[key]);
  161. }
  162. }
  163. if (isApplyAdd) {
  164. for (const key of Object.keys(diff.add)) {
  165. result[key] = _.cloneDeep(diff.add[key]);
  166. }
  167. }
  168. if (isApplyDel && diff.del.length) {
  169. for (const key of diff.del) {
  170. delete result[key];
  171. }
  172. if (_.isArray(result))
  173. result = result.filter(v => v);
  174. }
  175. return result;
  176. }
  177. export function parseQuery(str) {
  178. if (typeof str != 'string' || str.length == 0)
  179. return {};
  180. let s = str.split('&');
  181. let s_length = s.length;
  182. let bit, query = {}, first, second;
  183. for (let i = 0; i < s_length; i++) {
  184. bit = s[i].split('=');
  185. first = decodeURIComponent(bit[0]);
  186. if (first.length == 0)
  187. continue;
  188. second = decodeURIComponent(bit[1]);
  189. if (typeof query[first] == 'undefined')
  190. query[first] = second;
  191. else
  192. if (query[first] instanceof Array)
  193. query[first].push(second);
  194. else
  195. query[first] = [query[first], second];
  196. }
  197. return query;
  198. }
  199. export function escapeXml(str) {
  200. return str.replace(/&/g, '&amp;')
  201. .replace(/</g, '&lt;')
  202. .replace(/>/g, '&gt;')
  203. .replace(/"/g, '&quot;')
  204. .replace(/'/g, '&apos;')
  205. ;
  206. }
  207. export function keyEventToCode(event) {
  208. let result = [];
  209. let code = event.code;
  210. const modCode = code.substring(0, 3);
  211. if (event.metaKey && modCode != 'Met')
  212. result.push('Meta');
  213. if (event.ctrlKey && modCode != 'Con')
  214. result.push('Ctrl');
  215. if (event.shiftKey && modCode != 'Shi')
  216. result.push('Shift');
  217. if (event.altKey && modCode != 'Alt')
  218. result.push('Alt');
  219. if (modCode == 'Dig') {
  220. code = code.substring(5, 6);
  221. } else if (modCode == 'Key') {
  222. code = code.substring(3, 4);
  223. }
  224. result.push(code);
  225. return result.join('+');
  226. }
  227. export function userHotKeysObjectSwap(userHotKeys) {
  228. let result = {};
  229. for (const [name, codes] of Object.entries(userHotKeys)) {
  230. for (const code of codes) {
  231. result[code] = name;
  232. }
  233. }
  234. return result;
  235. }