mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-09-16 14:57:15 +00:00
0f216a0d4d
* feat(provider): support Codex subscriptions with ChatGPT sign-in * style: format Codex live integration test * fix(provider): preserve Codex identity in temporary model tests * fix(web): portal provider selector without dialog overflow * fix(web): allow native scrolling in provider dropdown * fix(provider): surface safe Codex quota and upstream errors * fix(web): provide reliable Codex copy feedback in dialogs * feat(provider): confirm cascade deletion from edit dialog * fix(persistence): discard connections after failed commit * fix(web): polish provider loading and confirmation motion --------- Co-authored-by: dadachann <185672915+dadachann@users.noreply.github.com>
40 lines
1.2 KiB
TypeScript
40 lines
1.2 KiB
TypeScript
/** Copy text using the Clipboard API, with a focus-trap-safe legacy fallback. */
|
|
export async function copyToClipboard(text: string): Promise<boolean> {
|
|
try {
|
|
if (navigator.clipboard?.writeText) {
|
|
await navigator.clipboard.writeText(text);
|
|
return true;
|
|
}
|
|
} catch {
|
|
// Permission/security errors can include sensitive text; do not log them.
|
|
}
|
|
|
|
const previousFocus = document.activeElement as HTMLElement | null;
|
|
const textArea = document.createElement('textarea');
|
|
try {
|
|
textArea.value = text;
|
|
textArea.style.position = 'fixed';
|
|
textArea.style.left = '-999999px';
|
|
textArea.style.top = '-999999px';
|
|
// Radix modal focus scopes reject focus on elements appended to body.
|
|
const container =
|
|
previousFocus?.closest('[role="dialog"], [role="alertdialog"]') ??
|
|
document.body;
|
|
container.appendChild(textArea);
|
|
textArea.focus({ preventScroll: true });
|
|
textArea.select();
|
|
if (
|
|
document.activeElement !== textArea ||
|
|
textArea.selectionEnd !== text.length
|
|
)
|
|
return false;
|
|
return document.execCommand('copy');
|
|
} catch {
|
|
return false;
|
|
} finally {
|
|
textArea.remove();
|
|
if (previousFocus?.isConnected)
|
|
previousFocus.focus({ preventScroll: true });
|
|
}
|
|
}
|