GIF89a
import AsyncHandler from "../../utils/AsyncHandler.js";
import Content from "../../models/content.model.js";
import ApiResponse from "../../utils/ApiRespinseHandler.js";
import User from "../../models/user.model.js";
import { roleContaints, contentStatus } from "../../validators/constaints.js";
import YoutubeVideoModel from '../../models/youtube.url.model.js';
import YoutubeModel from "../../models/youtube.model.js";
export const getHomeData = AsyncHandler(async (req, res) => {
const limit = 10;
// Helper functions to fetch data
const fetchByFlag = async (flag) => {
// Handle potential case difference in flags (IsNew vs isNew, isRecommended vs IsRecommended)
const flagLower = flag.charAt(0).toLowerCase() + flag.slice(1);
const flagUpper = flag.charAt(0).toUpperCase() + flag.slice(1);
return await Content.find({
$and: [
{
$or: [
{ [flagUpper]: true },
{ [flagLower]: true }
]
},
{
$or: [
{ status: { $regex: new RegExp(`^${contentStatus.active}$`, "i") } },
{ status: { $exists: false } },
{ status: null }
]
}
]
})
.populate({ path: "catId", select: "catName" })
.populate({ path: "contentOf", select: "fullName avatar role" })
.limit(limit)
.sort({ createdAt: -1 });
};
const fetchByRole = async (role, extraUserQuery = {}, returnUsers = false) => {
// Handle potential array of roles or single role
const roleQuery = Array.isArray(role)
? { $in: role.map(r => new RegExp(`^${r}$`, "i")) }
: { $regex: new RegExp(`^${role}$`, "i") };
const users = await User.find({
role: roleQuery,
// Check for both boolean true and string "true" for isVarifiedAsArtist if it exists in extraUserQuery
...(extraUserQuery.isVarifiedAsArtist !== undefined ? {
$or: [
{ isVarifiedAsArtist: true },
{ isVarifiedAsArtist: "true" }
]
} : {}),
// Ensure user is active
$or: [
{ status: { $regex: new RegExp(`^active$`, "i") } },
{ status: { $exists: false } },
{ status: null }
]
}).select("fullName avatar role services experties location studio status");
if (returnUsers) {
// If returnUsers is true, we return the users limited by global limit
const limitedUsers = users.slice(0, limit);
return { contents: limitedUsers, userCount: users.length };
}
const userIds = users.map(u => u._id);
const contents = await Content.find({
$and: [
{ contentOf: { $in: userIds } },
{
$or: [
{ status: { $regex: new RegExp(`^${contentStatus.active}$`, "i") } },
{ status: { $exists: false } },
{ status: null }
]
}
]
})
.populate({ path: "catId", select: "catName" })
.populate({ path: "contentOf", select: "fullName avatar role" })
.limit(limit)
.sort({ createdAt: -1 });
return { contents, userCount: users.length };
};
const [newArrival, recommended, lyrics, music, studio, youtubeVideos, channels] = await Promise.all([
fetchByFlag("IsNew"),
fetchByFlag("isRecommended"),
// Lyrics: Check for ARTIST or LYRICS role, must be verified
fetchByRole([roleContaints.artist, "LYRICS"], { isVarifiedAsArtist: true }),
// Music: Check for MUSICIAN or MUSIC role
fetchByRole([roleContaints.musician, "MUSIC"]),
// Studio: Check for STUDIO role, return as users
fetchByRole(roleContaints.studio, {}, true),
// YouTube Videos
YoutubeVideoModel.find().limit(limit).sort({ createdAt: -1 }),
// YouTube Channels
YoutubeModel.find().limit(limit).sort({ createdAt: -1 })
]);
return res.status(200).json(
new ApiResponse(200, "Home data fetched successfully", {
newArrival,
recommended,
lyrics: lyrics.contents,
music: music.contents,
studio: studio.contents,
youtubeVideos: youtubeVideos,
channels: channels,
// Debug info
debug: {
lyricsUserCount: lyrics.userCount,
musicUserCount: music.userCount,
studioUserCount: studio.userCount,
newArrivalCount: newArrival.length,
recommendedCount: recommended.length,
youtubeCount: youtubeVideos.length,
channelsCount: channels.length
}
})
);
});