Skip to content

Commit ffb155b

Browse files
Fix crash when clearing during active search
1 parent bf93614 commit ffb155b

1 file changed

Lines changed: 110 additions & 32 deletions

File tree

HDEncode-Search-Plus.user.js

Lines changed: 110 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
let isStoppingNow = false;
5353
let uiRefreshQueued = false;
5454
let suppressObserverUntil = 0;
55+
let pendingClearAfterStop = false;
56+
let clearRetryTimer = null;
5557

5658
const seenReleaseLinks = new Set();
5759
const linkCache = new Map();
@@ -432,14 +434,6 @@
432434
return '';
433435
}
434436

435-
function getCategory(item) {
436-
const links = Array.from(item.querySelectorAll('.calidad4 a'));
437-
const hrefs = links.map(a => a.href || a.getAttribute('href') || '');
438-
if (hrefs.some(h => h.includes('tv-packs'))) return 'tv-packs';
439-
if (hrefs.some(h => h.includes('tv-shows'))) return 'tv-shows';
440-
return 'movies';
441-
}
442-
443437
function getItemKey(item) {
444438
return item.querySelector('h5 a')?.href ||
445439
item.querySelector('h5 a')?.textContent?.trim() ||
@@ -483,12 +477,28 @@
483477
}
484478
}
485479

480+
function syncCategorySelectToLocation() {
481+
const select = document.getElementById('f-category');
482+
if (!select) return;
483+
484+
const href = window.location.href.replace(/\/+$/, '/');
485+
const options = [
486+
'https://hdencode.org/tag/movies/',
487+
'https://hdencode.org/tag/tv-shows/',
488+
'https://hdencode.org/tag/tv-packs/',
489+
'https://hdencode.org/top-downloads/',
490+
'https://hdencode.org/quality/2160p/'
491+
];
492+
493+
const matched = options.find(url => href.startsWith(url));
494+
select.value = matched || 'https://hdencode.org/tag/movies/';
495+
}
496+
486497
function getFilterValues() {
487498
return {
488499
onlyDV: document.getElementById('f-dv')?.checked || false,
489500
onlyHDR: document.getElementById('f-hdr')?.checked || false,
490501
res: document.getElementById('f-res')?.value || '',
491-
category: document.getElementById('f-category')?.value || '',
492502
minRating: parseFloat(document.getElementById('f-rating')?.value) || 0,
493503
minSize: parseFloat(document.getElementById('f-minsize')?.value) || 0,
494504
maxSize: parseFloat(document.getElementById('f-maxsize')?.value) || Infinity,
@@ -501,7 +511,6 @@
501511
if (f.onlyDV && !hasDV(item)) return false;
502512
if (f.onlyHDR && !hasHDR(item)) return false;
503513
if (f.res && getResolution(item) !== f.res) return false;
504-
if (f.category && getCategory(item) !== f.category) return false;
505514
if (getRating(item) < f.minRating) return false;
506515

507516
const size = getSize(item);
@@ -514,7 +523,7 @@
514523
function saveFilters() {
515524
const data = {};
516525
for (const el of document.querySelectorAll(`#${SCRIPT_ID}-bar input, #${SCRIPT_ID}-bar select`)) {
517-
if (el.id === 'f-pagelimit') continue;
526+
if (el.id === 'f-pagelimit' || el.id === 'f-category') continue;
518527
data[el.id] = el.type === 'checkbox' ? el.checked : el.value;
519528
}
520529
try {
@@ -526,7 +535,7 @@
526535
try {
527536
const data = JSON.parse(localStorage.getItem('hdencodeFilters') || '{}');
528537
for (const [id, val] of Object.entries(data)) {
529-
if (id === 'f-pagelimit') continue;
538+
if (id === 'f-pagelimit' || id === 'f-category') continue;
530539
const el = document.getElementById(id);
531540
if (!el) continue;
532541
if (el.type === 'checkbox') el.checked = val;
@@ -684,6 +693,7 @@
684693

685694
const stopBtn = document.getElementById('f-stop-loading');
686695
const loadBtn = document.getElementById('f-loadall');
696+
687697
if (stopBtn) {
688698
stopBtn.style.display = 'none';
689699
stopBtn.disabled = false;
@@ -694,13 +704,21 @@
694704
}
695705

696706
function stopLoading() {
697-
if (!isLoadingPages && !abortController) return;
707+
if (!isLoadingPages && !abortController) {
708+
if (pendingClearAfterStop && rootContainer) {
709+
pendingClearAfterStop = false;
710+
clearFilters(rootContainer);
711+
}
712+
return;
713+
}
714+
698715
if (isStoppingNow) return;
699716

700717
const didAbort = abortActiveLoading('user-stop');
701718

702719
const stopBtn = document.getElementById('f-stop-loading');
703720
const loadBtn = document.getElementById('f-loadall');
721+
704722
if (stopBtn) stopBtn.disabled = true;
705723
if (loadBtn) loadBtn.disabled = true;
706724

@@ -710,56 +728,98 @@
710728
if (!didAbort) {
711729
finishStopUI();
712730
queueUIRefresh(rootContainer);
731+
732+
if (pendingClearAfterStop && rootContainer) {
733+
pendingClearAfterStop = false;
734+
clearFilters(rootContainer);
735+
}
713736
}
714737
}
715738

716739
function clearFilters(container) {
717740
if (clearInProgress) return;
741+
742+
if (isLoadingPages || abortController || isStoppingNow) {
743+
pendingClearAfterStop = true;
744+
stopLoading();
745+
746+
clearTimeout(clearRetryTimer);
747+
clearRetryTimer = setTimeout(function waitForStop() {
748+
if (isLoadingPages || abortController || isStoppingNow) {
749+
clearRetryTimer = setTimeout(waitForStop, 60);
750+
return;
751+
}
752+
753+
pendingClearAfterStop = false;
754+
clearFilters(container);
755+
}, 60);
756+
757+
return;
758+
}
759+
718760
clearInProgress = true;
719761
suppressObserverUntil = Date.now() + 1000;
720762

721763
try {
722764
clearTimeout(refreshTimer);
765+
clearTimeout(clearRetryTimer);
723766
pauseObserver();
724767

725-
abortActiveLoading('clear');
726-
727768
for (const el of document.querySelectorAll(`#${SCRIPT_ID}-bar input, #${SCRIPT_ID}-bar select`)) {
728-
if (el.id === 'f-pagelimit') el.value = 'all';
729-
else if (el.type === 'checkbox') el.checked = false;
730-
else el.value = '';
769+
if (el.id === 'f-pagelimit') {
770+
el.value = 'all';
771+
} else if (el.id === 'f-category') {
772+
continue;
773+
} else if (el.type === 'checkbox') {
774+
el.checked = false;
775+
} else {
776+
el.value = '';
777+
}
731778
}
732779

733-
try { localStorage.removeItem('hdencodeFilters'); } catch (_) {}
780+
try {
781+
localStorage.removeItem('hdencodeFilters');
782+
} catch (_) {}
783+
784+
syncCategorySelectToLocation();
734785

735786
const stopBtn = document.getElementById('f-stop-loading');
736787
const loadBtn = document.getElementById('f-loadall');
788+
737789
if (stopBtn) {
738790
stopBtn.style.display = 'none';
739791
stopBtn.disabled = false;
740792
}
741-
if (loadBtn) loadBtn.disabled = false;
793+
794+
if (loadBtn) {
795+
loadBtn.disabled = false;
796+
}
797+
798+
abortController = null;
799+
isLoadingPages = false;
800+
isStoppingNow = false;
742801

743802
setStatus('');
803+
744804
const searchStatus = document.getElementById('f-search-status');
745805
if (searchStatus) {
746806
searchStatus.textContent = '';
747807
searchStatus.style.display = 'none';
748808
}
749809

750-
abortController = null;
751-
isLoadingPages = false;
752-
isStoppingNow = false;
753-
754810
applyFilters(container);
755811
styleVisibleResults(container);
756812
hideNativePagination();
757813
renderCustomPagination();
758-
updateEmptyState(container, Array.from(container.querySelectorAll('.fit.item')).some(item => item.style.display !== 'none'));
814+
updateEmptyState(
815+
container,
816+
Array.from(container.querySelectorAll('.fit.item')).some(item => item.style.display !== 'none')
817+
);
759818
} finally {
760819
setTimeout(() => {
761820
resumeObserver();
762821
}, 50);
822+
763823
clearInProgress = false;
764824
}
765825
}
@@ -849,7 +909,7 @@
849909

850910
loaded = 1;
851911

852-
let firstState = applyFilters(container);
912+
const firstState = applyFilters(container);
853913
if (getFilterValues().search) {
854914
setStatus(`${firstState.searchMatches} result(s) found so far — scanned ${loaded} page(s)`);
855915
} else {
@@ -965,6 +1025,15 @@
9651025
}
9661026
}
9671027

1028+
if (pendingClearAfterStop && !clearInProgress) {
1029+
setTimeout(() => {
1030+
if (rootContainer && !isLoadingPages && !abortController && !isStoppingNow) {
1031+
pendingClearAfterStop = false;
1032+
clearFilters(rootContainer);
1033+
}
1034+
}, 40);
1035+
}
1036+
9681037
setTimeout(() => {
9691038
const t = document.getElementById('f-load-status')?.textContent || '';
9701039
if (
@@ -1278,11 +1347,12 @@
12781347
</div>
12791348
12801349
<div class="fs-toolbar-right">
1281-
<select id="f-category" style="${INPUT_STYLE} width:110px;">
1282-
<option value="">All</option>
1283-
<option value="movies">Movies</option>
1284-
<option value="tv-shows">TV Shows</option>
1285-
<option value="tv-packs">TV Packs</option>
1350+
<select id="f-category" style="${INPUT_STYLE} width:150px;">
1351+
<option value="https://hdencode.org/tag/movies/">Movies</option>
1352+
<option value="https://hdencode.org/tag/tv-shows/">TV Shows</option>
1353+
<option value="https://hdencode.org/tag/tv-packs/">TV Packs</option>
1354+
<option value="https://hdencode.org/top-downloads/">Top Downloads</option>
1355+
<option value="https://hdencode.org/quality/2160p/">4K UHD</option>
12861356
</select>
12871357
</div>
12881358
</div>
@@ -1491,14 +1561,22 @@
14911561
});
14921562

14931563
for (const el of bar.querySelectorAll('input, select')) {
1494-
if (el.id === 'f-search') continue;
1564+
if (el.id === 'f-search' || el.id === 'f-category') continue;
14951565
el.addEventListener('input', () => applyFilters(container));
14961566
}
14971567

1568+
bar.querySelector('#f-category').addEventListener('change', function () {
1569+
const targetUrl = this.value;
1570+
if (targetUrl && window.location.href.replace(/\/+$/, '/') !== targetUrl.replace(/\/+$/, '/')) {
1571+
window.location.href = targetUrl;
1572+
}
1573+
});
1574+
14981575
searchInput.addEventListener('input', () => applyFilters(container));
14991576

15001577
buildGroupDropdown(container);
15011578
loadFilters();
1579+
syncCategorySelectToLocation();
15021580
applyFilters(container);
15031581
injectLinkButtons(container);
15041582
createObserver();

0 commit comments

Comments
 (0)