From f0bb2940a23902566d363a8ae9e522f7db7b34d1 Mon Sep 17 00:00:00 2001 From: gitstart Date: Wed, 5 Apr 2023 16:21:55 +0000 Subject: [PATCH] fix: Get Url in Storage does not work in Safari Co-authored-by: phunguyenmurcul <51897872+phunguyenmurcul@users.noreply.github.com> --- studio/lib/helpers.ts | 20 +++++++++++++++++-- .../storageExplorer/StorageExplorerStore.js | 14 +++++++------ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/studio/lib/helpers.ts b/studio/lib/helpers.ts index fa4fff11400..5a2f76c9f7c 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 d35a985f3d4..065c364d2ed 100644 --- a/studio/localStores/storageExplorer/StorageExplorerStore.js +++ b/studio/localStores/storageExplorer/StorageExplorerStore.js @@ -425,13 +425,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.`, @@ -440,7 +442,7 @@ class StorageExplorerStore { }) const fileCache = { id: file.id, - url: formattedUrl.toString(), + url: await signedUrlAsync, expiresIn: DEFAULT_EXPIRY, fetchedAt: Date.now(), }