реактивное отображение скелетонов вместо копирования

This commit is contained in:
Nastya 2025-06-10 23:04:01 +03:00
parent c396752ce6
commit a8d6db9f2d

@ -5,8 +5,8 @@ import { useCurrentQuiz } from "@/stores/quizes/hooks";
import { InfoPopover } from "@/ui_kit/InfoPopover"; import { InfoPopover } from "@/ui_kit/InfoPopover";
import TooltipClickInfo from "@/ui_kit/Toolbars/TooltipClickInfo"; import TooltipClickInfo from "@/ui_kit/Toolbars/TooltipClickInfo";
import { useDomainDefine } from "@/utils/hooks/useDomainDefine"; import { useDomainDefine } from "@/utils/hooks/useDomainDefine";
import { IconButton, ListItem, Typography, useTheme } from "@mui/material"; import { IconButton, ListItem, Skeleton, Typography, useTheme } from "@mui/material";
import { useMemo } from "react"; import { useEffect, useMemo, useState } from "react";
interface AuditoryLinkProps { interface AuditoryLinkProps {
item: AuditoryItem; item: AuditoryItem;
@ -20,16 +20,66 @@ export const AuditoryLink = ({ utmParams, item, index, onDelete }: AuditoryLinkP
const quiz = useCurrentQuiz(); const quiz = useCurrentQuiz();
const { isTestServer } = useDomainDefine(); const { isTestServer } = useDomainDefine();
const canCopy = useMemo(() => { const getCreatedTime = (timestamp: number) => {
if (!item.created_at) return true; // Если timestamp в секундах (10 цифр)
if (timestamp.toString().length === 10) {
return new Date(timestamp * 1000).getTime();
}
// Если timestamp в миллисекундах (13 цифр)
return new Date(timestamp).getTime();
};
const [isLoading, setIsLoading] = useState(() => {
if (!item.created_at) return false;
const now = new Date().getTime(); const now = new Date().getTime();
const created = new Date(item.created_at).getTime(); const created = getCreatedTime(item.created_at);
const diffInMinutes = (now - created) / (1000 * 60); const diffInMinutes = (now - created) / (1000 * 60);
return diffInMinutes >= 5; console.log('Initial state:', {
created_at: item.created_at,
format: item.created_at.toString().length === 10 ? 'seconds' : 'milliseconds',
now,
created,
diffInMinutes,
isLoading: diffInMinutes < 2
});
return diffInMinutes < 2;
});
useEffect(() => {
if (!item.created_at) return;
const now = new Date().getTime();
const created = getCreatedTime(item.created_at);
const diffInMinutes = (now - created) / (1000 * 60);
console.log('Effect check:', {
created_at: item.created_at,
format: item.created_at.toString().length === 10 ? 'seconds' : 'milliseconds',
now,
created,
diffInMinutes,
timeDiff: now - created
});
if (now - created < 1000) {
console.log('Setting loading to true for new link');
setIsLoading(true);
}
if (diffInMinutes < 2) {
const timeLeft = Math.ceil((2 - diffInMinutes) * 60 * 1000);
console.log('Setting timer for:', timeLeft, 'ms');
const timer = setTimeout(() => {
console.log('Timer finished, setting loading to false');
setIsLoading(false);
}, timeLeft);
return () => clearTimeout(timer);
}
}, [item.created_at]); }, [item.created_at]);
const handleCopy = (text: string) => { const handleCopy = (text: string) => {
if (!canCopy) return; if (isLoading) return;
navigator.clipboard.writeText(text); navigator.clipboard.writeText(text);
}; };
@ -77,21 +127,32 @@ export const AuditoryLink = ({ utmParams, item, index, onDelete }: AuditoryLinkP
<IconButton edge="end" aria-label="info" sx={{ color: theme.palette.brightPurple.main, p: 0, width: 18, height: 18 }}> <IconButton edge="end" aria-label="info" sx={{ color: theme.palette.brightPurple.main, p: 0, width: 18, height: 18 }}>
<TooltipClickInfo title={`Пол: ${item.sex === 0 ? "женский" : item.sex === 1 ? "мужской" : "оба"} \n Возраст: ${item.age}`} /> <TooltipClickInfo title={`Пол: ${item.sex === 0 ? "женский" : item.sex === 1 ? "мужской" : "оба"} \n Возраст: ${item.age}`} />
</IconButton> </IconButton>
<IconButton {isLoading ? (
edge="end" <Skeleton
aria-label="copy" variant="circular"
disabled={!canCopy} width={18}
sx={{ height={18}
color: canCopy ? theme.palette.brightPurple.main : theme.palette.grey[400], sx={{
p: 0, bgcolor: theme.palette.grey[400],
width: 18, marginRight: "-2px"
height: 18, }}
marginRight: "-2px" />
}} ) : (
onClick={() => handleCopy(linkText)} <IconButton
> edge="end"
<CopyIcon color={canCopy ? theme.palette.brightPurple.main : theme.palette.grey[400]} /> aria-label="copy"
</IconButton> sx={{
color: theme.palette.brightPurple.main,
p: 0,
width: 18,
height: 18,
marginRight: "-2px"
}}
onClick={() => handleCopy(linkText)}
>
<CopyIcon color={theme.palette.brightPurple.main} />
</IconButton>
)}
</> </>
} }
> >