Biomimicry-AI/Nexus
0
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 