Fix: file-manager and swarm-desktop bugs (#714)
- drive capacity display with stamp polling - download/upload progress handling - overlay and tooltip issues - FileMaganger readme - ultra-light mode handling - account feed view page - download media files - remove not found syncing link - fix ultra light node wallet page - tooltip issues --------- Co-authored-by: Andrei Mitrea <andrei.mitrea.hq@gmail.com> Co-authored-by: nidishk <nidishkrishnan45@gmail.com> Co-authored-by: Ferenc Sárai <sarai.ferenc@gmail.com> Co-authored-by: Nándor Komlódi <nandor.komlodi@gmail.com> Co-authored-by: rolandlor <33499567+rolandlor@users.noreply.github.com>
This commit is contained in:
@@ -14,7 +14,8 @@
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overscroll-behavior: contain;
|
||||
padding-right: 2px;
|
||||
padding-right: 14px;
|
||||
padding-left: 14px;
|
||||
}
|
||||
.fm-modal-window.fm-get-info-modal .fm-modal-window-body::-webkit-scrollbar,
|
||||
.fm-get-info-body::-webkit-scrollbar {
|
||||
@@ -66,23 +67,60 @@
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
max-width: 60%;
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
color: #111827;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.fm-copy-btn {
|
||||
margin-left: 6px;
|
||||
.fm-copyable-value {
|
||||
border: none;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
padding: 2px;
|
||||
line-height: 0;
|
||||
padding: 4px 8px;
|
||||
transition: background-color 0.2s;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.fm-copy-btn:hover {
|
||||
background: #f5f5f5;
|
||||
.fm-copyable-value:hover {
|
||||
background: rgba(237, 129, 49, 0.1);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.fm-copyable-value svg {
|
||||
flex-shrink: 0;
|
||||
color: rgb(237, 129, 49);
|
||||
}
|
||||
|
||||
.fm-copied-indicator {
|
||||
position: absolute;
|
||||
left: -70px;
|
||||
background: rgb(237, 129, 49);
|
||||
color: white;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
animation: fadeInOut 2s ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes fadeInOut {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateX(-10px);
|
||||
}
|
||||
10% {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
90% {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translateX(-10px);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ReactElement, useState } from 'react'
|
||||
import { ReactElement, useState, useEffect } from 'react'
|
||||
import './GetInfoModal.scss'
|
||||
import { Button } from '../Button/Button'
|
||||
import { createPortal } from 'react-dom'
|
||||
@@ -16,11 +16,28 @@ interface GetInfoModalProps {
|
||||
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]
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
Object.values(timeoutRef).forEach(timeout => clearTimeout(timeout))
|
||||
}
|
||||
}, [timeoutRef])
|
||||
|
||||
const handleCopy = async (prop: FileProperty) => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(prop.raw ?? prop.value)
|
||||
|
||||
if (timeoutRef[prop.key]) {
|
||||
clearTimeout(timeoutRef[prop.key])
|
||||
}
|
||||
|
||||
setCopiedKey(prop.key)
|
||||
window.setTimeout(() => setCopiedKey(null), 1200)
|
||||
|
||||
timeoutRef[prop.key] = setTimeout(() => {
|
||||
setCopiedKey(prev => (prev === prop.key ? null : prev))
|
||||
delete timeoutRef[prop.key]
|
||||
}, 2000)
|
||||
} catch {
|
||||
/* noop */
|
||||
}
|
||||
@@ -45,20 +62,20 @@ export function GetInfoModal({ name, onCancelClick, properties }: GetInfoModalPr
|
||||
{group.properties.map(prop => (
|
||||
<div key={prop.key} className="fm-get-info-modal-property-row">
|
||||
<span className="fm-get-info-modal-property-label">{prop.label}</span>
|
||||
<span className="fm-get-info-modal-property-value">
|
||||
{prop.value}
|
||||
{(prop.raw || prop.value.includes('...')) && (
|
||||
<button
|
||||
className="fm-copy-btn"
|
||||
onClick={() => handleCopy(prop)}
|
||||
aria-label={`Copy ${prop.label}`}
|
||||
type="button"
|
||||
title={copiedKey === prop.key ? 'Copied!' : 'Copy'}
|
||||
>
|
||||
<ClipboardIcon size="14px" />
|
||||
</button>
|
||||
)}
|
||||
</span>
|
||||
{prop.raw || prop.value.includes('...') ? (
|
||||
<button
|
||||
className="fm-get-info-modal-property-value fm-copyable-value"
|
||||
onClick={() => handleCopy(prop)}
|
||||
aria-label={`Copy ${prop.label}`}
|
||||
type="button"
|
||||
>
|
||||
<ClipboardIcon size="12px" />
|
||||
<span className="fm-copyable-value-text">{prop.value}</span>
|
||||
{copiedKey === prop.key && <span className="fm-copied-indicator">Copied!</span>}
|
||||
</button>
|
||||
) : (
|
||||
<span className="fm-get-info-modal-property-value">{prop.value}</span>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user