diff --git a/studio/lib/helpers.ts b/studio/lib/helpers.ts index 253acca7f8f..d11dd083a6e 100644 --- a/studio/lib/helpers.ts +++ b/studio/lib/helpers.ts @@ -153,10 +153,26 @@ export const snakeToCamel = (str: string) => group.toUpperCase().replace('-', '').replace('_', '') ) -export const copyToClipboard = (str: string, callback = () => {}) => { +/** + * Copy text content (string or Promise) into Clipboard. + * Safari doesn't support write text into clipboard async, so if you need to load + * text content async before coping, please use Promise for the 1st arg. + */ +export const copyToClipboard = (str: string | Promise, callback = () => {}) => { const focused = window.document.hasFocus() if (focused) { - window.navigator?.clipboard?.writeText(str).then(callback) + if (window.ClipboardItem) { + const text = new ClipboardItem({ + 'text/plain': Promise.resolve(str).then((text) => new Blob([text], { type: 'text/plain' })), + }) + window.navigator?.clipboard?.write([text]).then(callback) + + return + } + + Promise.resolve(str) + .then((text) => window.navigator?.clipboard?.writeText(text)) + .then(callback) } else { console.warn('Unable to copy to clipboard') } diff --git a/studio/localStores/storageExplorer/StorageExplorerStore.js b/studio/localStores/storageExplorer/StorageExplorerStore.js index 67a69895dd1..4c7ce2f14d5 100644 --- a/studio/localStores/storageExplorer/StorageExplorerStore.js +++ b/studio/localStores/storageExplorer/StorageExplorerStore.js @@ -407,13 +407,15 @@ class StorageExplorerStore { }) } else { // Need to generate signed URL, and might as well save it to cache as well - const signedUrl = await this.fetchFilePreview(file.name, expiresIn) - - try { - let formattedUrl = new URL(signedUrl) + const signedUrlAsync = this.fetchFilePreview(file.name, expiresIn).then((signedUrl) => { + const formattedUrl = new URL(signedUrl) formattedUrl.searchParams.set('t', new Date().toISOString()) - copyToClipboard(formattedUrl.toString(), () => { + return formattedUrl.toString() + }) + + try { + copyToClipboard(signedUrlAsync, () => { this.ui.setNotification({ category: 'success', message: `Copied URL for ${file.name} to clipboard.`, @@ -422,7 +424,7 @@ class StorageExplorerStore { }) const fileCache = { id: file.id, - url: formattedUrl.toString(), + url: await signedUrlAsync, expiresIn: DEFAULT_EXPIRY, fetchedAt: Date.now(), }