Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -43,6 +43,7 @@ CATEGORIES = {
|
|
| 43 |
"https://huggingface.co/spaces/ginipick/Change-Hair",
|
| 44 |
],
|
| 45 |
"Multimodal": [
|
|
|
|
| 46 |
"https://huggingface.co/spaces/ginigen/VEO3-Free",
|
| 47 |
"https://huggingface.co/spaces/ginigen/VEO3-Directors",
|
| 48 |
"https://huggingface.co/spaces/Heartsync/WAN2-1-fast-T2V-FusioniX",
|
|
@@ -497,13 +498,14 @@ body{margin:0;font-family:Nunito,sans-serif;background:#f6f8fb;}
|
|
| 497 |
</head>
|
| 498 |
<body>
|
| 499 |
<header style="text-align: center; padding: 20px; background: linear-gradient(135deg, #f6f8fb, #e2e8f0); border-bottom: 1px solid #ddd;">
|
| 500 |
-
<h1 style="margin-bottom: 10px;">🌟
|
| 501 |
<p>
|
| 502 |
<a href="https://discord.gg/openfreeai" target="_blank"><img src="https://img.shields.io/static/v1?label=Discord&message=Openfree%20AI&color=%230000ff&labelColor=%23800080&logo=discord&logoColor=white&style=for-the-badge" alt="badge"></a>
|
| 503 |
</p>
|
| 504 |
</header>
|
| 505 |
<div class="tabs" id="tabs"></div>
|
| 506 |
<div id="content"></div>
|
|
|
|
| 507 |
<script>
|
| 508 |
// Basic configuration
|
| 509 |
const cats = {{cats|tojson}};
|
|
@@ -511,6 +513,7 @@ const tabs = document.getElementById('tabs');
|
|
| 511 |
const content = document.getElementById('content');
|
| 512 |
let active = "";
|
| 513 |
let currentPage = 1;
|
|
|
|
| 514 |
// Simple utility functions
|
| 515 |
function loadHTML(url, callback) {
|
| 516 |
const xhr = new XMLHttpRequest();
|
|
@@ -522,6 +525,7 @@ function loadHTML(url, callback) {
|
|
| 522 |
};
|
| 523 |
xhr.send();
|
| 524 |
}
|
|
|
|
| 525 |
function makeRequest(url, method, data, callback) {
|
| 526 |
const xhr = new XMLHttpRequest();
|
| 527 |
xhr.open(method, url, true);
|
|
@@ -536,11 +540,13 @@ function makeRequest(url, method, data, callback) {
|
|
| 536 |
xhr.send();
|
| 537 |
}
|
| 538 |
}
|
|
|
|
| 539 |
function updateTabs() {
|
| 540 |
Array.from(tabs.children).forEach(b => {
|
| 541 |
b.classList.toggle('active', b.dataset.c === active);
|
| 542 |
});
|
| 543 |
}
|
|
|
|
| 544 |
// Tab handlers
|
| 545 |
function loadCategory(cat, page) {
|
| 546 |
if(cat === active && currentPage === page) return;
|
|
@@ -585,6 +591,7 @@ function loadCategory(cat, page) {
|
|
| 585 |
content.innerHTML = html;
|
| 586 |
});
|
| 587 |
}
|
|
|
|
| 588 |
function loadFavorites(page) {
|
| 589 |
if(active === 'Favorites' && currentPage === page) return;
|
| 590 |
active = 'Favorites';
|
|
@@ -642,6 +649,7 @@ function loadFavorites(page) {
|
|
| 642 |
content.innerHTML = html;
|
| 643 |
});
|
| 644 |
}
|
|
|
|
| 645 |
function loadManage() {
|
| 646 |
if(active === 'Manage') return;
|
| 647 |
active = 'Manage';
|
|
@@ -664,6 +672,7 @@ function loadManage() {
|
|
| 664 |
|
| 665 |
loadUrlList();
|
| 666 |
}
|
|
|
|
| 667 |
// URL management functions
|
| 668 |
function loadUrlList() {
|
| 669 |
makeRequest('/api/favorites?per_page=100', 'GET', null, function(data) {
|
|
@@ -693,6 +702,7 @@ function loadUrlList() {
|
|
| 693 |
urlList.innerHTML = html;
|
| 694 |
});
|
| 695 |
}
|
|
|
|
| 696 |
function addUrl() {
|
| 697 |
const url = document.getElementById('new-url').value.trim();
|
| 698 |
|
|
@@ -716,6 +726,7 @@ function addUrl() {
|
|
| 716 |
}
|
| 717 |
});
|
| 718 |
}
|
|
|
|
| 719 |
function editUrl(url) {
|
| 720 |
// Decode URL if it was previously escaped
|
| 721 |
const decodedUrl = url.replace(/\\'/g, "'");
|
|
@@ -739,6 +750,7 @@ function editUrl(url) {
|
|
| 739 |
}
|
| 740 |
});
|
| 741 |
}
|
|
|
|
| 742 |
function deleteUrl(url) {
|
| 743 |
// Decode URL if it was previously escaped
|
| 744 |
const decodedUrl = url.replace(/\\'/g, "'");
|
|
@@ -759,6 +771,7 @@ function deleteUrl(url) {
|
|
| 759 |
}
|
| 760 |
});
|
| 761 |
}
|
|
|
|
| 762 |
function showStatus(id, message, success) {
|
| 763 |
const status = document.getElementById(id);
|
| 764 |
status.textContent = message;
|
|
@@ -767,6 +780,7 @@ function showStatus(id, message, success) {
|
|
| 767 |
status.className = 'status';
|
| 768 |
}, 3000);
|
| 769 |
}
|
|
|
|
| 770 |
// Create tabs
|
| 771 |
// Favorites tab first
|
| 772 |
const favTab = document.createElement('button');
|
|
@@ -775,6 +789,7 @@ favTab.textContent = 'Favorites';
|
|
| 775 |
favTab.dataset.c = 'Favorites';
|
| 776 |
favTab.onclick = function() { loadFavorites(1); };
|
| 777 |
tabs.appendChild(favTab);
|
|
|
|
| 778 |
// Category tabs
|
| 779 |
cats.forEach(c => {
|
| 780 |
const b = document.createElement('button');
|
|
@@ -784,6 +799,7 @@ cats.forEach(c => {
|
|
| 784 |
b.onclick = function() { loadCategory(c, 1); };
|
| 785 |
tabs.appendChild(b);
|
| 786 |
});
|
|
|
|
| 787 |
// Manage tab last
|
| 788 |
const manageTab = document.createElement('button');
|
| 789 |
manageTab.className = 'tab manage';
|
|
@@ -791,6 +807,7 @@ manageTab.textContent = 'Manage';
|
|
| 791 |
manageTab.dataset.c = 'Manage';
|
| 792 |
manageTab.onclick = function() { loadManage(); };
|
| 793 |
tabs.appendChild(manageTab);
|
|
|
|
| 794 |
// Start with Favorites tab
|
| 795 |
loadFavorites(1);
|
| 796 |
</script>
|
|
|
|
| 43 |
"https://huggingface.co/spaces/ginipick/Change-Hair",
|
| 44 |
],
|
| 45 |
"Multimodal": [
|
| 46 |
+
"https://huggingface.co/spaces/Heartsync/VEO3-RealTime",
|
| 47 |
"https://huggingface.co/spaces/ginigen/VEO3-Free",
|
| 48 |
"https://huggingface.co/spaces/ginigen/VEO3-Directors",
|
| 49 |
"https://huggingface.co/spaces/Heartsync/WAN2-1-fast-T2V-FusioniX",
|
|
|
|
| 498 |
</head>
|
| 499 |
<body>
|
| 500 |
<header style="text-align: center; padding: 20px; background: linear-gradient(135deg, #f6f8fb, #e2e8f0); border-bottom: 1px solid #ddd;">
|
| 501 |
+
<h1 style="margin-bottom: 10px;">🌟AI Playground</h1>
|
| 502 |
<p>
|
| 503 |
<a href="https://discord.gg/openfreeai" target="_blank"><img src="https://img.shields.io/static/v1?label=Discord&message=Openfree%20AI&color=%230000ff&labelColor=%23800080&logo=discord&logoColor=white&style=for-the-badge" alt="badge"></a>
|
| 504 |
</p>
|
| 505 |
</header>
|
| 506 |
<div class="tabs" id="tabs"></div>
|
| 507 |
<div id="content"></div>
|
| 508 |
+
|
| 509 |
<script>
|
| 510 |
// Basic configuration
|
| 511 |
const cats = {{cats|tojson}};
|
|
|
|
| 513 |
const content = document.getElementById('content');
|
| 514 |
let active = "";
|
| 515 |
let currentPage = 1;
|
| 516 |
+
|
| 517 |
// Simple utility functions
|
| 518 |
function loadHTML(url, callback) {
|
| 519 |
const xhr = new XMLHttpRequest();
|
|
|
|
| 525 |
};
|
| 526 |
xhr.send();
|
| 527 |
}
|
| 528 |
+
|
| 529 |
function makeRequest(url, method, data, callback) {
|
| 530 |
const xhr = new XMLHttpRequest();
|
| 531 |
xhr.open(method, url, true);
|
|
|
|
| 540 |
xhr.send();
|
| 541 |
}
|
| 542 |
}
|
| 543 |
+
|
| 544 |
function updateTabs() {
|
| 545 |
Array.from(tabs.children).forEach(b => {
|
| 546 |
b.classList.toggle('active', b.dataset.c === active);
|
| 547 |
});
|
| 548 |
}
|
| 549 |
+
|
| 550 |
// Tab handlers
|
| 551 |
function loadCategory(cat, page) {
|
| 552 |
if(cat === active && currentPage === page) return;
|
|
|
|
| 591 |
content.innerHTML = html;
|
| 592 |
});
|
| 593 |
}
|
| 594 |
+
|
| 595 |
function loadFavorites(page) {
|
| 596 |
if(active === 'Favorites' && currentPage === page) return;
|
| 597 |
active = 'Favorites';
|
|
|
|
| 649 |
content.innerHTML = html;
|
| 650 |
});
|
| 651 |
}
|
| 652 |
+
|
| 653 |
function loadManage() {
|
| 654 |
if(active === 'Manage') return;
|
| 655 |
active = 'Manage';
|
|
|
|
| 672 |
|
| 673 |
loadUrlList();
|
| 674 |
}
|
| 675 |
+
|
| 676 |
// URL management functions
|
| 677 |
function loadUrlList() {
|
| 678 |
makeRequest('/api/favorites?per_page=100', 'GET', null, function(data) {
|
|
|
|
| 702 |
urlList.innerHTML = html;
|
| 703 |
});
|
| 704 |
}
|
| 705 |
+
|
| 706 |
function addUrl() {
|
| 707 |
const url = document.getElementById('new-url').value.trim();
|
| 708 |
|
|
|
|
| 726 |
}
|
| 727 |
});
|
| 728 |
}
|
| 729 |
+
|
| 730 |
function editUrl(url) {
|
| 731 |
// Decode URL if it was previously escaped
|
| 732 |
const decodedUrl = url.replace(/\\'/g, "'");
|
|
|
|
| 750 |
}
|
| 751 |
});
|
| 752 |
}
|
| 753 |
+
|
| 754 |
function deleteUrl(url) {
|
| 755 |
// Decode URL if it was previously escaped
|
| 756 |
const decodedUrl = url.replace(/\\'/g, "'");
|
|
|
|
| 771 |
}
|
| 772 |
});
|
| 773 |
}
|
| 774 |
+
|
| 775 |
function showStatus(id, message, success) {
|
| 776 |
const status = document.getElementById(id);
|
| 777 |
status.textContent = message;
|
|
|
|
| 780 |
status.className = 'status';
|
| 781 |
}, 3000);
|
| 782 |
}
|
| 783 |
+
|
| 784 |
// Create tabs
|
| 785 |
// Favorites tab first
|
| 786 |
const favTab = document.createElement('button');
|
|
|
|
| 789 |
favTab.dataset.c = 'Favorites';
|
| 790 |
favTab.onclick = function() { loadFavorites(1); };
|
| 791 |
tabs.appendChild(favTab);
|
| 792 |
+
|
| 793 |
// Category tabs
|
| 794 |
cats.forEach(c => {
|
| 795 |
const b = document.createElement('button');
|
|
|
|
| 799 |
b.onclick = function() { loadCategory(c, 1); };
|
| 800 |
tabs.appendChild(b);
|
| 801 |
});
|
| 802 |
+
|
| 803 |
// Manage tab last
|
| 804 |
const manageTab = document.createElement('button');
|
| 805 |
manageTab.className = 'tab manage';
|
|
|
|
| 807 |
manageTab.dataset.c = 'Manage';
|
| 808 |
manageTab.onclick = function() { loadManage(); };
|
| 809 |
tabs.appendChild(manageTab);
|
| 810 |
+
|
| 811 |
// Start with Favorites tab
|
| 812 |
loadFavorites(1);
|
| 813 |
</script>
|