|
import { useEffect, useState } from "react"; |
|
import { showToast } from "./components/ui-lib"; |
|
import Locale from "./locales"; |
|
|
|
export function trimTopic(topic: string) { |
|
return topic.replace(/[,。!?”“"、,.!?]*$/, ""); |
|
} |
|
|
|
export async function copyToClipboard(text: string) { |
|
try { |
|
await navigator.clipboard.writeText(text); |
|
showToast(Locale.Copy.Success); |
|
} catch (error) { |
|
const textArea = document.createElement("textarea"); |
|
textArea.value = text; |
|
document.body.appendChild(textArea); |
|
textArea.focus(); |
|
textArea.select(); |
|
try { |
|
document.execCommand("copy"); |
|
showToast(Locale.Copy.Success); |
|
} catch (error) { |
|
showToast(Locale.Copy.Failed); |
|
} |
|
document.body.removeChild(textArea); |
|
} |
|
} |
|
|
|
export function downloadAs(text: string, filename: string) { |
|
const element = document.createElement("a"); |
|
element.setAttribute( |
|
"href", |
|
"data:text/plain;charset=utf-8," + encodeURIComponent(text), |
|
); |
|
element.setAttribute("download", filename); |
|
|
|
element.style.display = "none"; |
|
document.body.appendChild(element); |
|
|
|
element.click(); |
|
|
|
document.body.removeChild(element); |
|
} |
|
|
|
export function isIOS() { |
|
const userAgent = navigator.userAgent.toLowerCase(); |
|
return /iphone|ipad|ipod/.test(userAgent); |
|
} |
|
|
|
export function useWindowSize() { |
|
const [size, setSize] = useState({ |
|
width: window.innerWidth, |
|
height: window.innerHeight, |
|
}); |
|
|
|
useEffect(() => { |
|
const onResize = () => { |
|
setSize({ |
|
width: window.innerWidth, |
|
height: window.innerHeight, |
|
}); |
|
}; |
|
|
|
window.addEventListener("resize", onResize); |
|
|
|
return () => { |
|
window.removeEventListener("resize", onResize); |
|
}; |
|
}, []); |
|
|
|
return size; |
|
} |
|
|
|
export const MOBILE_MAX_WIDTH = 600; |
|
export function useMobileScreen() { |
|
const { width } = useWindowSize(); |
|
|
|
return width <= MOBILE_MAX_WIDTH; |
|
} |
|
|
|
export function isMobileScreen() { |
|
if (typeof window === "undefined") { |
|
return false; |
|
} |
|
return window.innerWidth <= MOBILE_MAX_WIDTH; |
|
} |
|
|
|
export function isFirefox() { |
|
return ( |
|
typeof navigator !== "undefined" && /firefox/i.test(navigator.userAgent) |
|
); |
|
} |
|
|
|
export function selectOrCopy(el: HTMLElement, content: string) { |
|
const currentSelection = window.getSelection(); |
|
|
|
if (currentSelection?.type === "Range") { |
|
return false; |
|
} |
|
|
|
copyToClipboard(content); |
|
|
|
return true; |
|
} |
|
|
|
function getDomContentWidth(dom: HTMLElement) { |
|
const style = window.getComputedStyle(dom); |
|
const paddingWidth = |
|
parseFloat(style.paddingLeft) + parseFloat(style.paddingRight); |
|
const width = dom.clientWidth - paddingWidth; |
|
return width; |
|
} |
|
|
|
function getOrCreateMeasureDom(id: string, init?: (dom: HTMLElement) => void) { |
|
let dom = document.getElementById(id); |
|
|
|
if (!dom) { |
|
dom = document.createElement("span"); |
|
dom.style.position = "absolute"; |
|
dom.style.wordBreak = "break-word"; |
|
dom.style.fontSize = "14px"; |
|
dom.style.transform = "translateY(-200vh)"; |
|
dom.style.pointerEvents = "none"; |
|
dom.style.opacity = "0"; |
|
dom.id = id; |
|
document.body.appendChild(dom); |
|
init?.(dom); |
|
} |
|
|
|
return dom!; |
|
} |
|
|
|
export function autoGrowTextArea(dom: HTMLTextAreaElement) { |
|
const measureDom = getOrCreateMeasureDom("__measure"); |
|
const singleLineDom = getOrCreateMeasureDom("__single_measure", (dom) => { |
|
dom.innerText = "TEXT_FOR_MEASURE"; |
|
}); |
|
|
|
const width = getDomContentWidth(dom); |
|
measureDom.style.width = width + "px"; |
|
measureDom.innerText = dom.value.trim().length > 0 ? dom.value : "1"; |
|
|
|
const lineWrapCount = Math.max(0, dom.value.split("\n").length - 1); |
|
const height = parseFloat(window.getComputedStyle(measureDom).height); |
|
const singleLineHeight = parseFloat( |
|
window.getComputedStyle(singleLineDom).height, |
|
); |
|
|
|
const rows = Math.round(height / singleLineHeight) + lineWrapCount; |
|
|
|
return rows; |
|
} |
|
|
|
export function getCSSVar(varName: string) { |
|
return getComputedStyle(document.body).getPropertyValue(varName).trim(); |
|
} |
|
|