fix: filter endpoint and episodes AJAX loading

- Fix filter endpoint to always include keyword parameter
- Fix episodes to load via AJAX endpoint
- Episodes now properly populate from /ajax/episode/list/:id
This commit is contained in:
Sʜɪɴᴇɪ Nᴏᴜᴢᴇɴ
2026-06-08 16:00:04 +05:30
parent 8269dcea8b
commit 87d6d4dbf2
2 changed files with 54 additions and 27 deletions
+49 -26
View File
@@ -1,41 +1,64 @@
import * as cheerio from "cheerio"; import * as cheerio from "cheerio";
import axios from "axios"; import axios from "axios";
import { headers } from "../configs/header.config.js"; import { headers } from "../configs/header.config.js";
import { URLS } from "../configs/dataUrl.js"; import { URLS, BASE_URL } from "../configs/dataUrl.js";
const extractEpisodeList = async (slug) => { const extractEpisodeList = async (slug) => {
try { try {
const url = URLS.watch(slug); const infoUrl = URLS.watch(slug);
const { data } = await axios.get(url, { headers }); const { data: infoData } = await axios.get(infoUrl, { headers });
const $ = cheerio.load(data); const $ = cheerio.load(infoData);
const animeId = parseInt($("#watch-main").attr("data-id")) || 0; const animeId = parseInt($("#watch-main").attr("data-id")) || 0;
const episodes = []; if (!animeId) {
$("#w-episodes a[data-num], #w-episodes a[data-slug]").each((i, el) => { return { animeId: 0, slug, totalEpisodes: 0, episodes: [] };
const epId = $(el).attr("data-id") || $(el).attr("data-ep-id") || ""; }
const epNum = parseInt($(el).attr("data-num")) || i + 1;
const epSlug = $(el).attr("data-slug") || "";
const epTitle = $(el).find(".ep-title, .ep-name").text().trim() || "";
const isActive = $(el).hasClass("active") || false;
const href = $(el).attr("href") || "";
episodes.push({ try {
id: epId, const ajaxUrl = `${BASE_URL}/ajax/episode/list/${animeId}`;
episode_no: epNum, const { data: ajaxData } = await axios.get(ajaxUrl, {
slug: epSlug, headers: {
title: epTitle, ...headers,
active: isActive, "X-Requested-With": "XMLHttpRequest"
href }
}); });
});
return { const $ep = cheerio.load(ajaxData);
animeId,
slug, const episodes = [];
totalEpisodes: episodes.length, $ep("a[data-num], a[data-ep-id]").each((i, el) => {
episodes const epId = $ep(el).attr("data-ep-id") || $ep(el).attr("data-id") || "";
}; const epNum = parseInt($ep(el).attr("data-num")) || i + 1;
const epSlug = $ep(el).attr("data-slug") || "";
const href = $ep(el).attr("href") || "";
const epTitle = $ep(el).find(".ep-title, .ep-name").text().trim() || "";
const isActive = $ep(el).hasClass("active") || false;
episodes.push({
id: epId,
episode_no: epNum,
slug: epSlug,
title: epTitle,
active: isActive,
href
});
});
return {
animeId,
slug,
totalEpisodes: episodes.length,
episodes
};
} catch (ajaxError) {
return {
animeId,
slug,
totalEpisodes: 0,
episodes: []
};
}
} catch (error) { } catch (error) {
throw error; throw error;
} }
+5 -1
View File
@@ -9,7 +9,11 @@ const extractFilter = async (params) => {
try { try {
const queryParams = new URLSearchParams(); const queryParams = new URLSearchParams();
if (params.keyword) queryParams.set("keyword", params.keyword); if (params.keyword) {
queryParams.set("keyword", params.keyword);
} else {
queryParams.set("keyword", "");
}
if (params.genre) { if (params.genre) {
const genres = params.genre.split(",").map(g => GENRE_IDS[g.trim().toLowerCase()] || g.trim()); const genres = params.genre.split(",").map(g => GENRE_IDS[g.trim().toLowerCase()] || g.trim());