Files
sub2api/frontend/src/composables/useClipboard.ts

66 lines
1.5 KiB
TypeScript
Raw Normal View History

2025-12-18 13:50:39 +08:00
import { ref } from 'vue'
import { useAppStore } from '@/stores/app'
2025-12-27 15:16:52 +08:00
/**
* Clipboard APIHTTPS/localhost
*/
function isClipboardSupported(): boolean {
return !!(navigator.clipboard && window.isSecureContext)
}
/**
* 使 textarea + execCommand
* 使 textarea input
*/
function fallbackCopy(text: string): boolean {
const textarea = document.createElement('textarea')
textarea.value = text
textarea.style.cssText = 'position:fixed;left:-9999px;top:-9999px'
document.body.appendChild(textarea)
textarea.select()
try {
return document.execCommand('copy')
} finally {
document.body.removeChild(textarea)
}
}
2025-12-18 13:50:39 +08:00
export function useClipboard() {
const appStore = useAppStore()
const copied = ref(false)
2025-12-27 15:16:52 +08:00
const copyToClipboard = async (
text: string,
successMessage = 'Copied to clipboard'
): Promise<boolean> => {
2025-12-18 13:50:39 +08:00
if (!text) return false
2025-12-27 15:16:52 +08:00
let success = false
if (isClipboardSupported()) {
try {
await navigator.clipboard.writeText(text)
success = true
} catch {
success = fallbackCopy(text)
}
} else {
success = fallbackCopy(text)
}
if (success) {
2025-12-18 13:50:39 +08:00
copied.value = true
appStore.showSuccess(successMessage)
setTimeout(() => {
copied.value = false
}, 2000)
2025-12-27 15:16:52 +08:00
} else {
appStore.showError('Copy failed')
2025-12-18 13:50:39 +08:00
}
2025-12-27 15:16:52 +08:00
return success
2025-12-18 13:50:39 +08:00
}
2025-12-27 15:16:52 +08:00
return { copied, copyToClipboard }
2025-12-18 13:50:39 +08:00
}