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
+34 -11
View File
@@ -1,24 +1,39 @@
import * as cheerio from "cheerio";
import axios from "axios";
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) => {
try {
const url = URLS.watch(slug);
const { data } = await axios.get(url, { headers });
const $ = cheerio.load(data);
const infoUrl = URLS.watch(slug);
const { data: infoData } = await axios.get(infoUrl, { headers });
const $ = cheerio.load(infoData);
const animeId = parseInt($("#watch-main").attr("data-id")) || 0;
if (!animeId) {
return { animeId: 0, slug, totalEpisodes: 0, episodes: [] };
}
try {
const ajaxUrl = `${BASE_URL}/ajax/episode/list/${animeId}`;
const { data: ajaxData } = await axios.get(ajaxUrl, {
headers: {
...headers,
"X-Requested-With": "XMLHttpRequest"
}
});
const $ep = cheerio.load(ajaxData);
const episodes = [];
$("#w-episodes a[data-num], #w-episodes a[data-slug]").each((i, el) => {
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") || "";
$ep("a[data-num], a[data-ep-id]").each((i, el) => {
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,
@@ -36,6 +51,14 @@ const extractEpisodeList = async (slug) => {
totalEpisodes: episodes.length,
episodes
};
} catch (ajaxError) {
return {
animeId,
slug,
totalEpisodes: 0,
episodes: []
};
}
} catch (error) {
throw error;
}
+5 -1
View File
@@ -9,7 +9,11 @@ const extractFilter = async (params) => {
try {
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) {
const genres = params.genre.split(",").map(g => GENRE_IDS[g.trim().toLowerCase()] || g.trim());