Fix copy link
This commit is contained in:
@@ -5,10 +5,10 @@ import * as THREE from 'three';
|
|||||||
import JSZip from 'jszip';
|
import JSZip from 'jszip';
|
||||||
import { AppConfig, GeneratedPart, LayoutSplits } from '../types';
|
import { AppConfig, GeneratedPart, LayoutSplits } from '../types';
|
||||||
import { createBinGeometry, generateSTL, exportSTL } from '../services/geometryGenerator';
|
import { createBinGeometry, generateSTL, exportSTL } from '../services/geometryGenerator';
|
||||||
import { Download, Package, Info, Loader2, Share2, Check, Ruler } from 'lucide-react';
|
import { Download, Package, Info, Loader2, Share2, Check, Ruler, Copy } from 'lucide-react';
|
||||||
import { generateShareUrl } from '../utils/share'; // <--- Импорт утилиты
|
import { generateShareUrl } from '../utils/share';
|
||||||
|
|
||||||
// ... (DrawerFrame и BinMesh остаются без изменений) ...
|
// --- DrawerFrame (Каркас) ---
|
||||||
const DrawerFrame = ({ config }: { config: AppConfig }) => {
|
const DrawerFrame = ({ config }: { config: AppConfig }) => {
|
||||||
const { width, depth, height } = config.drawer;
|
const { width, depth, height } = config.drawer;
|
||||||
const offset = 0.5;
|
const offset = 0.5;
|
||||||
@@ -22,6 +22,7 @@ const DrawerFrame = ({ config }: { config: AppConfig }) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- BinMesh (Ячейка) ---
|
||||||
interface BinMeshProps {
|
interface BinMeshProps {
|
||||||
part: GeneratedPart;
|
part: GeneratedPart;
|
||||||
thickness: number;
|
thickness: number;
|
||||||
@@ -49,12 +50,11 @@ const BinMesh: React.FC<BinMeshProps> = ({ part, thickness, isSelected, onClick
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Основной компонент ---
|
// --- PreviewStep (Основной) ---
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
parts: GeneratedPart[];
|
parts: GeneratedPart[];
|
||||||
config: AppConfig;
|
config: AppConfig;
|
||||||
splits: LayoutSplits; // <--- Добавили splits в пропсы
|
splits: LayoutSplits;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PreviewStep: React.FC<Props> = ({ parts, config, splits }) => {
|
export const PreviewStep: React.FC<Props> = ({ parts, config, splits }) => {
|
||||||
@@ -100,18 +100,55 @@ export const PreviewStep: React.FC<Props> = ({ parts, config, splits }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Логика кнопки "Поделиться"
|
// --- Улучшенная функция копирования ---
|
||||||
const handleShare = () => {
|
const handleShare = async () => {
|
||||||
const url = generateShareUrl(config, splits);
|
const url = generateShareUrl(config, splits);
|
||||||
navigator.clipboard.writeText(url).then(() => {
|
let success = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. Пробуем современный API (работает только на HTTPS или localhost)
|
||||||
|
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||||
|
await navigator.clipboard.writeText(url);
|
||||||
|
success = true;
|
||||||
|
} else {
|
||||||
|
throw new Error('Clipboard API unavailable');
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// 2. Если не вышло (например, HTTP), используем Fallback метод
|
||||||
|
try {
|
||||||
|
const textArea = document.createElement("textarea");
|
||||||
|
textArea.value = url;
|
||||||
|
|
||||||
|
// Делаем элемент невидимым, но частью DOM
|
||||||
|
textArea.style.position = "fixed";
|
||||||
|
textArea.style.left = "-9999px";
|
||||||
|
textArea.style.top = "0";
|
||||||
|
document.body.appendChild(textArea);
|
||||||
|
|
||||||
|
textArea.focus();
|
||||||
|
textArea.select();
|
||||||
|
|
||||||
|
const result = document.execCommand('copy');
|
||||||
|
document.body.removeChild(textArea);
|
||||||
|
|
||||||
|
if (result) success = true;
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Copy failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success) {
|
||||||
setShareUrlCopied(true);
|
setShareUrlCopied(true);
|
||||||
setTimeout(() => setShareUrlCopied(false), 2000);
|
setTimeout(() => setShareUrlCopied(false), 3000);
|
||||||
});
|
} else {
|
||||||
|
// 3. Если совсем ничего не помогло, показываем промпт
|
||||||
|
prompt("Не удалось скопировать автоматически. Скопируйте ссылку вручную:", url);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col h-full">
|
<div className="flex flex-col h-full">
|
||||||
{/* 1. ВЕРХНЯЯ ПАНЕЛЬ С РАЗМЕРАМИ И КНОПКОЙ SHARE */}
|
{/* Верхняя панель: Размеры + Поделиться */}
|
||||||
<div className="flex flex-col md:flex-row justify-between items-center bg-slate-800/80 p-4 rounded-xl border border-slate-700 mb-4 gap-4 backdrop-blur-sm shadow-lg">
|
<div className="flex flex-col md:flex-row justify-between items-center bg-slate-800/80 p-4 rounded-xl border border-slate-700 mb-4 gap-4 backdrop-blur-sm shadow-lg">
|
||||||
|
|
||||||
<div className="flex items-center gap-6">
|
<div className="flex items-center gap-6">
|
||||||
@@ -136,15 +173,15 @@ export const PreviewStep: React.FC<Props> = ({ parts, config, splits }) => {
|
|||||||
<button
|
<button
|
||||||
onClick={handleShare}
|
onClick={handleShare}
|
||||||
className={`
|
className={`
|
||||||
flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-semibold transition-all border
|
flex items-center gap-2 px-6 py-2 rounded-lg text-sm font-bold transition-all border shadow-md active:scale-95
|
||||||
${shareUrlCopied
|
${shareUrlCopied
|
||||||
? 'bg-green-600/20 border-green-500/50 text-green-400'
|
? 'bg-green-600 border-green-500 text-white shadow-green-900/20'
|
||||||
: 'bg-slate-700 hover:bg-slate-600 border-slate-600 text-white'
|
: 'bg-blue-600 hover:bg-blue-500 border-blue-500 text-white shadow-blue-900/20'
|
||||||
}
|
}
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
{shareUrlCopied ? <Check size={16} /> : <Share2 size={16} />}
|
{shareUrlCopied ? <Check size={18} /> : <Share2 size={18} />}
|
||||||
{shareUrlCopied ? 'Ссылка скопирована!' : 'Поделиться проектом'}
|
{shareUrlCopied ? 'СКОПИРОВАНО!' : 'Поделиться проектом'}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user