Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -386,6 +386,7 @@ HTML_TEMPLATE = """
|
|
| 386 |
|
| 387 |
.variant-item.error {
|
| 388 |
opacity: 0.6;
|
|
|
|
| 389 |
}
|
| 390 |
|
| 391 |
.variant-item.error .variant-text {
|
|
@@ -448,6 +449,10 @@ HTML_TEMPLATE = """
|
|
| 448 |
opacity: 1;
|
| 449 |
}
|
| 450 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 451 |
.loading {
|
| 452 |
display: inline-block;
|
| 453 |
width: 18px;
|
|
@@ -549,7 +554,7 @@ HTML_TEMPLATE = """
|
|
| 549 |
</div>
|
| 550 |
<ul class="translation-list">
|
| 551 |
{% for trans in marian %}
|
| 552 |
-
<li class="translation-item" onclick="selectTranslation(this, {{ trans | tojson }})"
|
| 553 |
<span class="translation-text">{{ trans }}</span>
|
| 554 |
<svg class="check-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3">
|
| 555 |
<polyline points="20 6 9 17 4 12"></polyline>
|
|
@@ -579,7 +584,7 @@ HTML_TEMPLATE = """
|
|
| 579 |
<div class="variant-grid">
|
| 580 |
{% for variant_name, variant_data in libre.items() %}
|
| 581 |
{% if variant_data.success %}
|
| 582 |
-
<div class="variant-item" onclick="selectVariant(this, {{ variant_data.text | tojson }})"
|
| 583 |
<div class="variant-header">
|
| 584 |
<span class="variant-name">{{ variant_name }}</span>
|
| 585 |
<span class="variant-code">{{ variant_data.code }}</span>
|
|
@@ -627,7 +632,7 @@ HTML_TEMPLATE = """
|
|
| 627 |
});
|
| 628 |
element.classList.add('selected');
|
| 629 |
selectedText = text;
|
| 630 |
-
copyText(text,
|
| 631 |
}
|
| 632 |
|
| 633 |
function selectVariant(element, text) {
|
|
@@ -636,31 +641,49 @@ HTML_TEMPLATE = """
|
|
| 636 |
});
|
| 637 |
element.classList.add('selected');
|
| 638 |
selectedText = text;
|
| 639 |
-
copyText(text,
|
| 640 |
}
|
| 641 |
|
| 642 |
async function copyText(text, showToast = true) {
|
| 643 |
-
|
| 644 |
-
|
| 645 |
-
|
| 646 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 647 |
}
|
| 648 |
-
}
|
| 649 |
-
|
| 650 |
-
|
| 651 |
-
|
| 652 |
-
|
| 653 |
-
|
| 654 |
-
|
| 655 |
-
|
| 656 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 657 |
}
|
| 658 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 659 |
}
|
| 660 |
|
| 661 |
-
function showToastMessage(message) {
|
| 662 |
const toast = document.getElementById('toast');
|
| 663 |
toast.textContent = message;
|
|
|
|
| 664 |
toast.classList.add('show');
|
| 665 |
setTimeout(() => toast.classList.remove('show'), 2000);
|
| 666 |
}
|
|
|
|
| 386 |
|
| 387 |
.variant-item.error {
|
| 388 |
opacity: 0.6;
|
| 389 |
+
cursor: default;
|
| 390 |
}
|
| 391 |
|
| 392 |
.variant-item.error .variant-text {
|
|
|
|
| 449 |
opacity: 1;
|
| 450 |
}
|
| 451 |
|
| 452 |
+
.toast.error {
|
| 453 |
+
background: #ef4444;
|
| 454 |
+
}
|
| 455 |
+
|
| 456 |
.loading {
|
| 457 |
display: inline-block;
|
| 458 |
width: 18px;
|
|
|
|
| 554 |
</div>
|
| 555 |
<ul class="translation-list">
|
| 556 |
{% for trans in marian %}
|
| 557 |
+
<li class="translation-item" onclick="selectTranslation(this, {{ trans | tojson }})">
|
| 558 |
<span class="translation-text">{{ trans }}</span>
|
| 559 |
<svg class="check-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3">
|
| 560 |
<polyline points="20 6 9 17 4 12"></polyline>
|
|
|
|
| 584 |
<div class="variant-grid">
|
| 585 |
{% for variant_name, variant_data in libre.items() %}
|
| 586 |
{% if variant_data.success %}
|
| 587 |
+
<div class="variant-item" onclick="selectVariant(this, {{ variant_data.text | tojson }})">
|
| 588 |
<div class="variant-header">
|
| 589 |
<span class="variant-name">{{ variant_name }}</span>
|
| 590 |
<span class="variant-code">{{ variant_data.code }}</span>
|
|
|
|
| 632 |
});
|
| 633 |
element.classList.add('selected');
|
| 634 |
selectedText = text;
|
| 635 |
+
copyText(text, true);
|
| 636 |
}
|
| 637 |
|
| 638 |
function selectVariant(element, text) {
|
|
|
|
| 641 |
});
|
| 642 |
element.classList.add('selected');
|
| 643 |
selectedText = text;
|
| 644 |
+
copyText(text, true);
|
| 645 |
}
|
| 646 |
|
| 647 |
async function copyText(text, showToast = true) {
|
| 648 |
+
let copied = false;
|
| 649 |
+
|
| 650 |
+
if (navigator.clipboard && window.isSecureContext) {
|
| 651 |
+
try {
|
| 652 |
+
await navigator.clipboard.writeText(text);
|
| 653 |
+
copied = true;
|
| 654 |
+
} catch (err) {
|
| 655 |
+
copied = false;
|
| 656 |
}
|
| 657 |
+
}
|
| 658 |
+
|
| 659 |
+
if (!copied) {
|
| 660 |
+
try {
|
| 661 |
+
const textArea = document.createElement('textarea');
|
| 662 |
+
textArea.value = text;
|
| 663 |
+
textArea.style.position = 'fixed';
|
| 664 |
+
textArea.style.left = '-9999px';
|
| 665 |
+
document.body.appendChild(textArea);
|
| 666 |
+
textArea.focus();
|
| 667 |
+
textArea.select();
|
| 668 |
+
copied = document.execCommand('copy');
|
| 669 |
+
document.body.removeChild(textArea);
|
| 670 |
+
} catch (err) {
|
| 671 |
+
copied = false;
|
| 672 |
}
|
| 673 |
}
|
| 674 |
+
|
| 675 |
+
if (showToast) {
|
| 676 |
+
showToastMessage(
|
| 677 |
+
copied ? 'Copied to clipboard!' : 'Copy failed — please copy manually',
|
| 678 |
+
!copied
|
| 679 |
+
);
|
| 680 |
+
}
|
| 681 |
}
|
| 682 |
|
| 683 |
+
function showToastMessage(message, isError = false) {
|
| 684 |
const toast = document.getElementById('toast');
|
| 685 |
toast.textContent = message;
|
| 686 |
+
toast.classList.toggle('error', isError);
|
| 687 |
toast.classList.add('show');
|
| 688 |
setTimeout(() => toast.classList.remove('show'), 2000);
|
| 689 |
}
|