fix copy btn and copy page btn
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
||||
} from '@mui/material';
|
||||
import { Delete, Add, Link as LinkIcon, OpenInNew, ContentCopy, Dns, Router, Edit, MoreVert, Remove, Refresh } from '@mui/icons-material';
|
||||
import api from '../api';
|
||||
import { copyToClipboard } from '../utils/copyToClipboard';
|
||||
import { Logger } from '../utils/logger';
|
||||
|
||||
interface Subscription {
|
||||
@@ -345,7 +346,7 @@ export default function SubscriptionsPage() {
|
||||
};
|
||||
|
||||
const handleCopyLink = async (uuid: string, tunnelId: string | number) => {
|
||||
await navigator.clipboard.writeText(getSubscriptionUrl(uuid, tunnelId));
|
||||
await copyToClipboard(getSubscriptionUrl(uuid, tunnelId));
|
||||
setSnackbar({ open: true, type: 'success', message: 'Ссылка на подписку скопирована' });
|
||||
};
|
||||
|
||||
@@ -602,7 +603,7 @@ export default function SubscriptionsPage() {
|
||||
/>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={() => navigator.clipboard.writeText(currentLinks.join('\n'))}>Копировать все</Button>
|
||||
<Button onClick={() => copyToClipboard(currentLinks.join('\n'))}>Копировать все</Button>
|
||||
<Button onClick={() => setLinksOpen(false)}>Закрыть</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Универсальная функция копирования текста в буфер обмена.
|
||||
* Работает и в secure (HTTPS/localhost), и в insecure (HTTP по IP) контекстах.
|
||||
* navigator.clipboard недоступен при не-HTTPS/не-localhost соединениях.
|
||||
*/
|
||||
export async function copyToClipboard(text: string): Promise<void> {
|
||||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||
await navigator.clipboard.writeText(text);
|
||||
} else {
|
||||
// Fallback для HTTP (не-localhost) — использует execCommand
|
||||
const textarea = document.createElement('textarea');
|
||||
textarea.value = text;
|
||||
textarea.style.position = 'fixed';
|
||||
textarea.style.left = '-9999px';
|
||||
textarea.style.top = '-9999px';
|
||||
document.body.appendChild(textarea);
|
||||
textarea.focus();
|
||||
textarea.select();
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
} finally {
|
||||
document.body.removeChild(textarea);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -259,16 +259,28 @@ export function generateSubscriptionHtmlWithQr(
|
||||
|
||||
function copyLink() {
|
||||
const link = document.getElementById('link-text').innerText;
|
||||
navigator.clipboard.writeText(link).then(() => {
|
||||
const btn = document.querySelector('.action-btn');
|
||||
const originalText = btn.innerHTML;
|
||||
btn.innerHTML = 'Скопировано!';
|
||||
btn.style.backgroundColor = 'var(--button-success)';
|
||||
setTimeout(() => {
|
||||
btn.innerHTML = originalText;
|
||||
btn.style.backgroundColor = 'var(--button-bg)';
|
||||
}, 2000);
|
||||
});
|
||||
let copied = false;
|
||||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||
navigator.clipboard.writeText(link).then(() => { copied = true; });
|
||||
}
|
||||
if (!copied) {
|
||||
const ta = document.createElement('textarea');
|
||||
ta.value = link;
|
||||
ta.style.position = 'fixed';
|
||||
ta.style.left = '-9999px';
|
||||
document.body.appendChild(ta);
|
||||
ta.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(ta);
|
||||
}
|
||||
const btn = document.querySelector('.action-btn');
|
||||
const originalText = btn.innerHTML;
|
||||
btn.innerHTML = 'Скопировано!';
|
||||
btn.style.backgroundColor = 'var(--button-success)';
|
||||
setTimeout(() => {
|
||||
btn.innerHTML = originalText;
|
||||
btn.style.backgroundColor = 'var(--button-bg)';
|
||||
}, 2000);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user