feat: sync and update with all changes from fork (#720)

* feat: sync and update with all changes from fork
* refactor: extract clipboard copy logic into custom hook
* fix: correct spelling of DEFAULT_REFRESH_FREQUENCY_MS in Stamps and WalletBalance providers
* refactor(ui-tests): replace fixed sleeps with condition-based waits
* fix: handle null values for size and granteeCount in infoGroups
* fix(lint): add newline at end of file in useClipboardCopy hook
* fix(ui-tests): page.goto URL
* refactor: update import paths for useClipboardCopy

---------

Co-authored-by: Ferenc Sárai <sarai.ferenc@gmail.com>
This commit is contained in:
Bálint Ujvári
2026-03-02 11:34:39 +01:00
committed by GitHub
parent b0f00a624a
commit 519c411db0
303 changed files with 16609 additions and 29415 deletions
@@ -1,11 +1,12 @@
import { ReactElement, useState, useEffect } from 'react'
import './GetInfoModal.scss'
import { Button } from '../Button/Button'
import { ReactElement, useEffect, useRef, useState } from 'react'
import { createPortal } from 'react-dom'
import InfoIcon from 'remixicon-react/InformationLineIcon'
import ClipboardIcon from 'remixicon-react/FileCopyLineIcon'
import InfoIcon from 'remixicon-react/InformationLineIcon'
import type { FileProperty, FilePropertyGroup } from '../../utils/infoGroups'
import { Button } from '../Button/Button'
import './GetInfoModal.scss'
interface GetInfoModalProps {
name: string
@@ -13,31 +14,35 @@ interface GetInfoModalProps {
onCancelClick: () => void
}
const COPY_TIMEOUT_MS = 2000
export function GetInfoModal({ name, onCancelClick, properties }: GetInfoModalProps): ReactElement {
const modalRoot = document.querySelector('.fm-main') || document.body
const [copiedKey, setCopiedKey] = useState<string | null>(null)
const timeoutRef = useState<{ [key: string]: NodeJS.Timeout }>({})[0]
const timeoutRef = useRef<Record<string, NodeJS.Timeout>>({})
useEffect(() => {
return () => {
Object.values(timeoutRef).forEach(timeout => clearTimeout(timeout))
// eslint-disable-next-line react-hooks/exhaustive-deps
Object.values(timeoutRef.current).forEach(clearTimeout)
}
}, [timeoutRef])
}, [])
const handleCopy = async (prop: FileProperty) => {
try {
await navigator.clipboard.writeText(prop.raw ?? prop.value)
if (timeoutRef[prop.key]) {
clearTimeout(timeoutRef[prop.key])
if (timeoutRef.current[prop.key]) {
clearTimeout(timeoutRef.current[prop.key])
}
setCopiedKey(prop.key)
timeoutRef[prop.key] = setTimeout(() => {
timeoutRef.current[prop.key] = setTimeout(() => {
setCopiedKey(prev => (prev === prop.key ? null : prev))
delete timeoutRef[prop.key]
}, 2000)
delete timeoutRef.current[prop.key]
}, COPY_TIMEOUT_MS)
} catch {
/* noop */
}