diff --git a/desktop/src/scripts/room.js b/desktop/src/scripts/room.js index 9e4fcb2..cf89c8c 100644 --- a/desktop/src/scripts/room.js +++ b/desktop/src/scripts/room.js @@ -1472,25 +1472,31 @@ const RoomsApp = (function() { copyInviteBtn.onclick = async () => { try { - console.log('Copying to clipboard:', inviteUrl); - await navigator.clipboard.writeText(inviteUrl); + console.log('Attempting to copy:', inviteUrl); - const originalHTML = copyInviteBtn.innerHTML; - copyInviteBtn.innerHTML = ` - - - - `; - copyInviteBtn.style.color = '#4ade80'; + const success = await copyToClipboard(inviteUrl); - setTimeout(() => { - copyInviteBtn.innerHTML = originalHTML; - copyInviteBtn.style.color = ''; - }, 2000); + if (success) { + const originalHTML = copyInviteBtn.innerHTML; + copyInviteBtn.innerHTML = ` + + + + `; + copyInviteBtn.style.color = '#4ade80'; - showCopyToast(window.__roomExposed ? 'Public link copied!' : 'Local link copied!'); + setTimeout(() => { + copyInviteBtn.innerHTML = originalHTML; + copyInviteBtn.style.color = ''; + }, 2000); + + showCopyToast(window.__roomExposed ? 'Public link copied!' : 'Local link copied!'); + } else { + showManualCopyModal(inviteUrl); + } } catch (err) { console.error('Failed to copy:', err); + showManualCopyModal(inviteUrl); } }; } @@ -1504,6 +1510,61 @@ const RoomsApp = (function() { if (room.currentVideo) loadVideo(room.currentVideo); } + function showManualCopyModal(text) { + const modal = document.createElement('div'); + modal.className = 'modal-overlay show'; + modal.innerHTML = ` + + `; + document.body.appendChild(modal); + + // Auto-seleccionar el texto + setTimeout(() => { + const input = modal.querySelector('input'); + if (input) input.select(); + }, 100); + } + + async function copyToClipboard(text) { + if (navigator.clipboard && window.isSecureContext) { + try { + await navigator.clipboard.writeText(text); + return true; + } catch (err) { + console.warn('Clipboard API failed, trying fallback:', err); + } + } + + try { + const textArea = document.createElement("textarea"); + textArea.value = text; + textArea.style.position = "fixed"; + textArea.style.left = "-999999px"; + textArea.style.top = "-999999px"; + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + + const successful = document.execCommand('copy'); + document.body.removeChild(textArea); + + if (successful) return true; + throw new Error('execCommand failed'); + } catch (err) { + console.error('All clipboard methods failed:', err); + return false; + } + } + async function initGlobalControls() { const hasAccess = isHost || (window.__userPermissions?.canManageQueue || false); if (!hasAccess || !extensionsReady) return; diff --git a/docker/src/scripts/room.js b/docker/src/scripts/room.js index 9e4fcb2..cf89c8c 100644 --- a/docker/src/scripts/room.js +++ b/docker/src/scripts/room.js @@ -1472,25 +1472,31 @@ const RoomsApp = (function() { copyInviteBtn.onclick = async () => { try { - console.log('Copying to clipboard:', inviteUrl); - await navigator.clipboard.writeText(inviteUrl); + console.log('Attempting to copy:', inviteUrl); - const originalHTML = copyInviteBtn.innerHTML; - copyInviteBtn.innerHTML = ` - - - - `; - copyInviteBtn.style.color = '#4ade80'; + const success = await copyToClipboard(inviteUrl); - setTimeout(() => { - copyInviteBtn.innerHTML = originalHTML; - copyInviteBtn.style.color = ''; - }, 2000); + if (success) { + const originalHTML = copyInviteBtn.innerHTML; + copyInviteBtn.innerHTML = ` + + + + `; + copyInviteBtn.style.color = '#4ade80'; - showCopyToast(window.__roomExposed ? 'Public link copied!' : 'Local link copied!'); + setTimeout(() => { + copyInviteBtn.innerHTML = originalHTML; + copyInviteBtn.style.color = ''; + }, 2000); + + showCopyToast(window.__roomExposed ? 'Public link copied!' : 'Local link copied!'); + } else { + showManualCopyModal(inviteUrl); + } } catch (err) { console.error('Failed to copy:', err); + showManualCopyModal(inviteUrl); } }; } @@ -1504,6 +1510,61 @@ const RoomsApp = (function() { if (room.currentVideo) loadVideo(room.currentVideo); } + function showManualCopyModal(text) { + const modal = document.createElement('div'); + modal.className = 'modal-overlay show'; + modal.innerHTML = ` + + `; + document.body.appendChild(modal); + + // Auto-seleccionar el texto + setTimeout(() => { + const input = modal.querySelector('input'); + if (input) input.select(); + }, 100); + } + + async function copyToClipboard(text) { + if (navigator.clipboard && window.isSecureContext) { + try { + await navigator.clipboard.writeText(text); + return true; + } catch (err) { + console.warn('Clipboard API failed, trying fallback:', err); + } + } + + try { + const textArea = document.createElement("textarea"); + textArea.value = text; + textArea.style.position = "fixed"; + textArea.style.left = "-999999px"; + textArea.style.top = "-999999px"; + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + + const successful = document.execCommand('copy'); + document.body.removeChild(textArea); + + if (successful) return true; + throw new Error('execCommand failed'); + } catch (err) { + console.error('All clipboard methods failed:', err); + return false; + } + } + async function initGlobalControls() { const hasAccess = isHost || (window.__userPermissions?.canManageQueue || false); if (!hasAccess || !extensionsReady) return;