All files / src/utils helpers.ts

3.61% Statements 3/83
2.77% Branches 1/36
5.26% Functions 1/19
3.7% Lines 3/81

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154                                                          1x                                                                                                                                                       1x 6x                                                                                              
import slugify from "@sindresorhus/slugify";
 
/** Copy given string to clipboard. Returns true if successful, false if failed. */
export function copyToClipboard(text: string): boolean {
  const textArea = document.createElement("textarea");
  textArea.style.position = "fixed";
  textArea.style.left = "-9999px";
  textArea.value = text;
  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();
  try {
    document.execCommand("copy");
  } catch (error) {
    console.error("Failed to copy text:", error);
    return false;
  }
  document.body.removeChild(textArea);
  return true;
}
 
export function downloadCanvasImage(canvas: HTMLCanvasElement, filename: string): void {
  const image = canvas.toDataURL();
  const link = document.createElement("a");
  link.download = filename;
  link.href = image;
  link.click();
}
 
export const copyImageSupported = "ClipboardItem" in window && navigator.clipboard && "write" in navigator.clipboard;
export function copyCanvasImage(canvas: HTMLCanvasElement): boolean {
  if (!copyImageSupported) {
    throw Error("Copying images not supported on this browser");
  }
  canvas.toBlob((blob) =>
    (navigator.clipboard as any).write([new (window as any).ClipboardItem({ "image/png": blob })]),
  );
  return true;
}
 
export function ellipsis(text: string, startLength: number, endLength: number): string {
  if (startLength + endLength + 2 >= text.length) {
    // +2 because there's reason to ellide something shorter than "..."
    return text;
  }
  return text.substr(0, startLength) + "..." + text.substr(text.length - endLength, text.length);
}
 
export function truncateDid(did: string, maxCharCount = 20): string {
  const overMaxCount = did.length > maxCharCount;
  return did.includes("did:web") ? did : overMaxCount ? hexEllipsis(did) : did;
}
 
/** Finds where "0x" hex value starts and takes start length from there. */
export function hexEllipsis(text: string, startLength = 4, endLength = 4): string {
  const addressIndex = text.indexOf("0x") === -1 ? text.lastIndexOf(":") + 1 : text.indexOf("0x") + 2;
  return ellipsis(text, addressIndex + startLength, endLength);
}
 
export function dateTimeFormat(date: Date): any {
  const year = new Intl.DateTimeFormat("en", { year: "numeric" }).format(date);
  const month = new Intl.DateTimeFormat("en", { month: "short" }).format(date);
  const day = new Intl.DateTimeFormat("en", { day: "2-digit" }).format(date);
  const dateFormatted = ` ${month} ${day}, ${year}`;
  const timeFormatted = new Intl.DateTimeFormat("en-US", { hour: "numeric", minute: "numeric" }).format(date);
  return { dateFormatted, timeFormatted };
}
 
/** <input type="datetime-local"> element requires a nonstandard time format ("yyyy-MM-ddThh:mm"). This converts from ISO datetime string into that format.  */
export function isoToDatetimeLocal(isoString: string): string {
  const offset = new Date().getTimezoneOffset() * 1000 * 60;
  const offsetDate = new Date(isoString).valueOf() - offset;
  return new Date(offsetDate).toISOString().substring(0, 16);
}
 
export function convertToCamelCase(s: string): string {
  return slugify(s).replace(/-./g, (x) => x.replace("-", "").toUpperCase());
}
export function convertToPascalCase(s: string): string {
  return slugify(s).replace(/(^|-)./g, (x) => x.replace("-", "").toUpperCase());
}
 
export function getAllUrlSearchParam(name: string): string[] {
  if (window.URLSearchParams) {
    const urlParams = new URLSearchParams(window.location.search.slice(1));
    return urlParams.getAll(name);
  } else {
    // eslint-disable-next-line no-useless-escape
    const nameForRegex = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    const regex = new RegExp("[\\?&]" + nameForRegex + "=([^&#]*)", "g");
    const output = [];
    let results: RegExpExecArray | null;
    // eslint-disable-next-line no-constant-condition
    while (true) {
      results = regex.exec(window.location.search);
      if (!results) {
        break;
      }
      output.push(decodeURIComponent(results[1].replace(/\+/g, " ")));
    }
    return output;
  }
}
 
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export const createMockApiRequest = (response?: any): ((...args: any[]) => Promise<any>) => {
  return (async (...args: any[]) => {
    return new Promise((resolve) =>
      setTimeout(() => {
        console.log("SertoUiContext mock API request resolving. Request args:", ...args);
        resolve(response);
      }, 500),
    );
  }) as any;
};
 
export interface NftIdentifierResult {
  contractAddress: string;
  tokenId: string;
  error: string;
}
 
export function getNftIdentifiersFromUrl(url: string): NftIdentifierResult {
  let contractAddress = "";
  let tokenId = "";
  let error = "";
  if (url) {
    const splitVal = url.split("?");
    if (splitVal && splitVal.length > 0) {
      url = splitVal[0];
    }
    const splitURL = url.split("/");
    const length = splitURL.length;
    if (length < 2) {
      error = "Contract Address or TokenID not found on URL";
    } else {
      const theorizedAddress = splitURL[length - 2];
      const addressMatch = theorizedAddress.startsWith("0x") && theorizedAddress.length == 42;
      if (!addressMatch) {
        error = "Unable to find Contract Address in provided URL";
      } else {
        contractAddress = theorizedAddress;
        const tokenIdMatch = splitURL[length - 1].match("[0-9]+");
        if (!tokenIdMatch || tokenIdMatch.length == 0) {
          error = "Unable to find Token ID in provided URL";
        } else {
          tokenId = tokenIdMatch[0];
        }
      }
    }
  }
  return { contractAddress, tokenId, error };
}