CoolFace
Apppublic

Biomimicry-AI/Nexus

sourceHugging Faceupdated 3y agoView on Hugging Face
0likes
utils.ts217 linesDownload Raw Back to app
1import { useEffect, useState } from "react";2import { showToast } from "./components/ui-lib";3import Locale from "./locales";4 5export function trimTopic(topic: string) {6  return topic.replace(/[,。!?”“"、,.!?]*$/, "");7}8 9export async function copyToClipboard(text: string) {10  try {11    if (window.__TAURI__) {12      window.__TAURI__.writeText(text);13    } else {14      await navigator.clipboard.writeText(text);15    }16 17    showToast(Locale.Copy.Success);18  } catch (error) {19    const textArea = document.createElement("textarea");20    textArea.value = text;21    document.body.appendChild(textArea);22    textArea.focus();23    textArea.select();24    try {25      document.execCommand("copy");26      showToast(Locale.Copy.Success);27    } catch (error) {28      showToast(Locale.Copy.Failed);29    }30    document.body.removeChild(textArea);31  }32}33 34export async function downloadAs(text: string, filename: string) {35  if (window.__TAURI__) {36    const result = await window.__TAURI__.dialog.save({37      defaultPath: `${filename}`,38      filters: [39        {40          name: `${filename.split('.').pop()} files`,41          extensions: [`${filename.split('.').pop()}`],42        },43        {44          name: "All Files",45          extensions: ["*"],46        },47      ],48    });49 50    if (result !== null) {51      try {52        await window.__TAURI__.fs.writeBinaryFile(53          result,54          new Uint8Array([...text].map((c) => c.charCodeAt(0)))55        );56        showToast(Locale.Download.Success);57      } catch (error) {58        showToast(Locale.Download.Failed);59      }60    } else {61      showToast(Locale.Download.Failed);62    }63  } else {64    const element = document.createElement("a");65    element.setAttribute(66      "href",67      "data:text/plain;charset=utf-8," + encodeURIComponent(text),68    );69  element.setAttribute("download", filename);70 71  element.style.display = "none";72  document.body.appendChild(element);73 74  element.click();75 76  document.body.removeChild(element);77}78}79export function readFromFile() {80  return new Promise<string>((res, rej) => {81    const fileInput = document.createElement("input");82    fileInput.type = "file";83    fileInput.accept = "application/json";84 85    fileInput.onchange = (event: any) => {86      const file = event.target.files[0];87      const fileReader = new FileReader();88      fileReader.onload = (e: any) => {89        res(e.target.result);90      };91      fileReader.onerror = (e) => rej(e);92      fileReader.readAsText(file);93    };94 95    fileInput.click();96  });97}98 99export function isIOS() {100  const userAgent = navigator.userAgent.toLowerCase();101  return /iphone|ipad|ipod/.test(userAgent);102}103 104export function useWindowSize() {105  const [size, setSize] = useState({106    width: window.innerWidth,107    height: window.innerHeight,108  });109 110  useEffect(() => {111    const onResize = () => {112      setSize({113        width: window.innerWidth,114        height: window.innerHeight,115      });116    };117 118    window.addEventListener("resize", onResize);119 120    return () => {121      window.removeEventListener("resize", onResize);122    };123  }, []);124 125  return size;126}127 128export const MOBILE_MAX_WIDTH = 600;129export function useMobileScreen() {130  const { width } = useWindowSize();131 132  return width <= MOBILE_MAX_WIDTH;133}134 135export function isFirefox() {136  return (137    typeof navigator !== "undefined" && /firefox/i.test(navigator.userAgent)138  );139}140 141export function selectOrCopy(el: HTMLElement, content: string) {142  const currentSelection = window.getSelection();143 144  if (currentSelection?.type === "Range") {145    return false;146  }147 148  copyToClipboard(content);149 150  return true;151}152 153function getDomContentWidth(dom: HTMLElement) {154  const style = window.getComputedStyle(dom);155  const paddingWidth =156    parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);157  const width = dom.clientWidth - paddingWidth;158  return width;159}160 161function getOrCreateMeasureDom(id: string, init?: (dom: HTMLElement) => void) {162  let dom = document.getElementById(id);163 164  if (!dom) {165    dom = document.createElement("span");166    dom.style.position = "absolute";167    dom.style.wordBreak = "break-word";168    dom.style.fontSize = "14px";169    dom.style.transform = "translateY(-200vh)";170    dom.style.pointerEvents = "none";171    dom.style.opacity = "0";172    dom.id = id;173    document.body.appendChild(dom);174    init?.(dom);175  }176 177  return dom!;178}179 180export function autoGrowTextArea(dom: HTMLTextAreaElement) {181  const measureDom = getOrCreateMeasureDom("__measure");182  const singleLineDom = getOrCreateMeasureDom("__single_measure", (dom) => {183    dom.innerText = "TEXT_FOR_MEASURE";184  });185 186  const width = getDomContentWidth(dom);187  measureDom.style.width = width + "px";188  measureDom.innerText = dom.value !== "" ? dom.value : "1";189  measureDom.style.fontSize = dom.style.fontSize;190  const endWithEmptyLine = dom.value.endsWith("\n");191  const height = parseFloat(window.getComputedStyle(measureDom).height);192  const singleLineHeight = parseFloat(193    window.getComputedStyle(singleLineDom).height,194  );195 196  const rows =197    Math.round(height / singleLineHeight) + (endWithEmptyLine ? 1 : 0);198 199  return rows;200}201 202export function getCSSVar(varName: string) {203  return getComputedStyle(document.body).getPropertyValue(varName).trim();204}205 206/**207 * Detects Macintosh208 */209export function isMacOS(): boolean {210  if (typeof window !== "undefined") {211    let userAgent = window.navigator.userAgent.toLocaleLowerCase();212    const macintosh = /iphone|ipad|ipod|macintosh/.test(userAgent)213    return !!macintosh214  }215  return false216}217