Mirror of https://github.com/roostorg/osprey github.com/roostorg/osprey
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ui: fallback text copying for insecure hosts (#45)

Co-authored-by: Ryan Prior <4389854+ryanprior@users.noreply.github.com>

authored by

hailey
Ryan Prior
and committed by
GitHub
ddd1ea19 41688547

+40 -1
+7 -1
osprey_ui/src/components/common/CopyLinkButton.tsx
··· 1 1 import * as React from 'react'; 2 2 import { CheckCircleOutlined, LinkOutlined } from '@ant-design/icons'; 3 3 import { message, Button } from 'antd'; 4 + import { copyText } from '../../lib/copyText'; 4 5 5 6 interface CopyLinkButtonProps { 6 7 link: string; ··· 25 26 }, [showCopySuccess]); 26 27 27 28 const handleCopyLink = async () => { 28 - await navigator.clipboard.writeText(link); 29 + try { 30 + await copyText(link); 31 + } catch (err) { 32 + message.error(`Error copying text to clipboard: ${err}`); 33 + return; 34 + } 29 35 message.success('Link copied to clipboard', 1); 30 36 setShowCopySuccess(true); 31 37 };
+33
osprey_ui/src/lib/copyText.ts
··· 1 + // the clipboard api is not available when using a non-secure host (aside from localhost) 2 + // this can be pretty common for some setups that are running i.e. on tailscale, so ideally 3 + // we don't want to break things when a user tries to copy text somewhere. here we use a 4 + // fallback when either that api is not available or `secureContext` is false 5 + // see: https://developer.mozilla.org/en-US/docs/Web/API/Navigator/clipboard 6 + export async function copyText(text: string): Promise<void> { 7 + if (navigator.clipboard && window.isSecureContext) { 8 + return navigator.clipboard.writeText(text); 9 + } else { 10 + // create a textarea that gets appended to the body, then focus+copy text 11 + const body = document.body; 12 + const textarea = document.createElement('textarea'); 13 + textarea.setAttribute('aria-hidden', 'true'); 14 + body.appendChild(textarea); 15 + textarea.value = text; 16 + textarea.focus(); 17 + textarea.select(); 18 + 19 + // NOTE: execCommand is actually deprecated, so this might break in future browser versions 20 + // unfortunately. we'll log an error in the event that things do fail. 21 + // see: https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand 22 + try { 23 + document.execCommand('copy'); 24 + } catch (err) { 25 + console.error(`copyText: fallback failed: ${err}`); 26 + // still throw the error so that calling code can optionally alert the user that the copy 27 + // failed 28 + throw err; 29 + } finally { 30 + textarea.remove(); 31 + } 32 + } 33 + }