more upgrade
This commit is contained in:
@@ -2,7 +2,8 @@
|
||||
let currentPage = 1;
|
||||
const perPage = 12;
|
||||
const renderedVideoIds = new Set();
|
||||
let currentQuery = "";
|
||||
let hasNextPage = true;
|
||||
let isLoading = false;
|
||||
|
||||
// 2. Observer Definition (Must be defined before initApp uses it)
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
@@ -74,11 +75,15 @@ async function InitializeServerStatus() {
|
||||
async function loadVideos() {
|
||||
const session = JSON.parse(localStorage.getItem('session'));
|
||||
if (!session) return;
|
||||
if (isLoading || !hasNextPage) return;
|
||||
|
||||
const searchInput = document.getElementById('search-input');
|
||||
const query = searchInput ? searchInput.value : "";
|
||||
|
||||
// Build the request body
|
||||
let body = {
|
||||
channel: session.channel.id,
|
||||
query: currentQuery,
|
||||
query: query || "",
|
||||
page: currentPage,
|
||||
perPage: perPage,
|
||||
server: session.server
|
||||
@@ -94,6 +99,7 @@ async function loadVideos() {
|
||||
});
|
||||
|
||||
try {
|
||||
isLoading = true;
|
||||
const response = await fetch('/api/videos', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
@@ -101,17 +107,22 @@ async function loadVideos() {
|
||||
});
|
||||
const videos = await response.json();
|
||||
renderVideos(videos);
|
||||
hasNextPage = videos && videos.pageInfo ? videos.pageInfo.hasNextPage !== false : true;
|
||||
currentPage++;
|
||||
ensureViewportFilled();
|
||||
} catch (err) {
|
||||
console.error("Failed to load videos:", err);
|
||||
} finally {
|
||||
isLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
function renderVideos(videos) {
|
||||
const grid = document.getElementById('video-grid');
|
||||
if (!grid) return;
|
||||
|
||||
videos.items.forEach(v => {
|
||||
|
||||
const items = videos && Array.isArray(videos.items) ? videos.items : [];
|
||||
items.forEach(v => {
|
||||
if (renderedVideoIds.has(v.id)) return;
|
||||
|
||||
const card = document.createElement('div');
|
||||
@@ -170,8 +181,8 @@ function closePlayer() {
|
||||
}
|
||||
|
||||
function handleSearch(value) {
|
||||
currentQuery = value || "";
|
||||
currentPage = 1;
|
||||
hasNextPage = true;
|
||||
renderedVideoIds.clear();
|
||||
const grid = document.getElementById('video-grid');
|
||||
if (grid) grid.innerHTML = "";
|
||||
@@ -224,12 +235,23 @@ function buildDefaultOptions(channel) {
|
||||
|
||||
function resetAndReload() {
|
||||
currentPage = 1;
|
||||
hasNextPage = true;
|
||||
renderedVideoIds.clear();
|
||||
const grid = document.getElementById('video-grid');
|
||||
if (grid) grid.innerHTML = "";
|
||||
loadVideos();
|
||||
}
|
||||
|
||||
function ensureViewportFilled() {
|
||||
if (!hasNextPage || isLoading) return;
|
||||
const grid = document.getElementById('video-grid');
|
||||
if (!grid) return;
|
||||
const contentHeight = grid.getBoundingClientRect().bottom;
|
||||
if (contentHeight < window.innerHeight + 120) {
|
||||
window.setTimeout(() => loadVideos(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
function renderMenu() {
|
||||
const session = getSession();
|
||||
const serverEntries = getServerEntries();
|
||||
@@ -239,6 +261,7 @@ function renderMenu() {
|
||||
const sourcesList = document.getElementById('sources-list');
|
||||
const addSourceBtn = document.getElementById('add-source-btn');
|
||||
const sourceInput = document.getElementById('source-input');
|
||||
const reloadChannelBtn = document.getElementById('reload-channel-btn');
|
||||
|
||||
if (!sourceSelect || !channelSelect || !filtersContainer) return;
|
||||
|
||||
@@ -389,6 +412,12 @@ function renderMenu() {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (reloadChannelBtn) {
|
||||
reloadChannelBtn.onclick = () => {
|
||||
resetAndReload();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function renderFilters(container, session) {
|
||||
|
||||
BIN
frontend/favicon.ico
Normal file
BIN
frontend/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 523 B |
@@ -13,6 +13,9 @@
|
||||
<input type="text" id="search-input" placeholder="Search videos..." oninput="handleSearch(this.value)">
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button class="icon-btn reload-toggle" id="reload-channel-btn" title="Reload Channel">
|
||||
<img class="icon-svg" src="https://cdn.jsdelivr.net/npm/heroicons@2.0.13/24/outline/arrow-path.svg" alt="Reload">
|
||||
</button>
|
||||
<button class="icon-btn menu-toggle" onclick="toggleDrawer('menu')" title="Menu">
|
||||
<img class="icon-svg" src="https://cdn.jsdelivr.net/npm/heroicons@2.0.13/24/outline/bars-3.svg" alt="Menu">
|
||||
</button>
|
||||
|
||||
@@ -327,6 +327,8 @@ body.theme-light .input-row input:focus {
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
transition: all 0.2s ease;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
|
||||
Reference in New Issue
Block a user