Fix Kurz-URL: Shortening server-seitig beim Erstellen, kein CORS, sync kopieren

This commit is contained in:
2026-06-06 01:55:14 +02:00
parent 6c3ab332c0
commit 9d05233fe1
3 changed files with 42 additions and 44 deletions

View File

@@ -170,8 +170,6 @@ function UploadShareManager({ toast }) {
const [busy, setBusy] = useState(false);
const [copied, setCopied] = useState(null);
const [sharePws, setSharePws] = useState({}); // {shareId: password} für Passwort-Kopieren
const [shortUrls, setShortUrls] = useState({}); // {shareId: shortUrl}
const [shortening, setShortening] = useState(null); // shareId being shortened
const load = () => api('/upload-shares').then(d=>{ setShares(d.shares||[]); setFolder(d.folder); }).catch(()=>{});
useEffect(()=>{ load(); },[]);
@@ -220,41 +218,22 @@ function UploadShareManager({ toast }) {
setShortening(null);
};
const doCopy = (text) => {
// Fallback-Kopieren ohne navigator.clipboard (funktioniert auch in PWA/mobile)
const copyLink = (shareId, token, shortUrl) => {
// Kurz-URL vom Server nehmen (bereits beim Erstellen generiert), sonst Original
const url = shortUrl || `${window.location.origin}/u/${token}`;
// Synchron kopieren kein await nötig
if (navigator.clipboard) {
navigator.clipboard.writeText(text).catch(() => {
const ta = document.createElement('textarea');
ta.value = text; ta.style.cssText='position:fixed;opacity:0';
document.body.appendChild(ta); ta.focus(); ta.select();
document.execCommand('copy'); document.body.removeChild(ta);
});
} else {
const ta = document.createElement('textarea');
ta.value = text; ta.style.cssText='position:fixed;opacity:0';
document.body.appendChild(ta); ta.focus(); ta.select();
document.execCommand('copy'); document.body.removeChild(ta);
}
navigator.clipboard.writeText(url).catch(() => fallbackCopy(url));
} else { fallbackCopy(url); }
setCopied(token); setTimeout(()=>setCopied(null), 2500);
};
const copyLink = (shareId, token) => {
// SOFORT kopieren (synchron, innerhalb User-Gesture-Kontext)
const url = shortUrls[shareId] || `${window.location.origin}/u/${token}`;
doCopy(url);
setCopied(token); setTimeout(()=>setCopied(null), 2500);
// Falls noch keine Kurz-URL: im Hintergrund generieren (für nächsten Klick)
if (!shortUrls[shareId] && shortening !== shareId) {
setShortening(shareId);
const fullUrl = `${window.location.origin}/u/${token}`;
fetch(`https://is.gd/create.php?format=simple&url=${encodeURIComponent(fullUrl)}`)
.then(r => r.text())
.then(short => {
if (short.startsWith('http')) setShortUrls(p=>({...p,[shareId]:short.trim()}));
})
.catch(()=>{})
.finally(()=>setShortening(null));
}
const fallbackCopy = (text) => {
const ta = document.createElement('textarea');
ta.value = text; ta.style.cssText = 'position:fixed;top:0;left:0;opacity:0.01';
document.body.appendChild(ta); ta.focus(); ta.select();
try { document.execCommand('copy'); } catch {}
document.body.removeChild(ta);
};
const loadLogs = () => {
@@ -366,9 +345,9 @@ function UploadShareManager({ toast }) {
<div style={{display:'flex',gap:5,flexShrink:0}}>
{!!s.is_active && !expired && (
<>
<button onClick={()=>copyLink(s.id,s.token)}
<button onClick={()=>copyLink(s.id, s.token, s.short_url)}
style={{...S.btn(copied===s.token?'#4ecdc4':'#ffe66d',copied!==s.token),fontSize:10,padding:'4px 10px'}}>
{shortening===s.id?'…':copied===s.token?'✓ Kopiert':'📋 Link'}
{copied===s.token?'✓ Kopiert':'📋 Link'}
</button>
{sharePws[s.id] && (
<button onClick={()=>{ navigator.clipboard?.writeText(sharePws[s.id]).then(()=>toast('Passwort kopiert ✓')).catch(()=>toast(sharePws[s.id])); }}