utils.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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 isEmptyObjDiff(diff) {
  108. return (!_.isObject(diff) || !diff.__isDiff ||
  109. (!Object.keys(diff.change).length &&
  110. !Object.keys(diff.add).length &&
  111. !diff.del.length
  112. )
  113. );
  114. }
  115. export function applyObjDiff(obj, diff, isAddChanged) {
  116. const result = _.cloneDeep(obj);
  117. if (!diff.__isDiff)
  118. return result;
  119. const change = diff.change;
  120. for (const key of Object.keys(change)) {
  121. if (result.hasOwnProperty(key)) {
  122. if (_.isObject(change[key])) {
  123. result[key] = applyObjDiff(result[key], change[key], isAddChanged);
  124. } else {
  125. result[key] = _.cloneDeep(change[key]);
  126. }
  127. } else if (isAddChanged) {
  128. result[key] = _.cloneDeep(change[key]);
  129. }
  130. }
  131. for (const key of Object.keys(diff.add)) {
  132. result[key] = _.cloneDeep(diff.add[key]);
  133. }
  134. for (const key of diff.del) {
  135. delete result[key];
  136. }
  137. return result;
  138. }
  139. export function parseQuery(str) {
  140. if (typeof str != 'string' || str.length == 0)
  141. return {};
  142. let s = str.split('&');
  143. let s_length = s.length;
  144. let bit, query = {}, first, second;
  145. for (let i = 0; i < s_length; i++) {
  146. bit = s[i].split('=');
  147. first = decodeURIComponent(bit[0]);
  148. if (first.length == 0)
  149. continue;
  150. second = decodeURIComponent(bit[1]);
  151. if (typeof query[first] == 'undefined')
  152. query[first] = second;
  153. else
  154. if (query[first] instanceof Array)
  155. query[first].push(second);
  156. else
  157. query[first] = [query[first], second];
  158. }
  159. return query;
  160. }