Sort 4K shelf by newest 4K file discovery, not title first-seen.
This commit is contained in:
parent
06a022089b
commit
4c15a37783
2 changed files with 47 additions and 23 deletions
|
|
@ -508,9 +508,8 @@ async function getMovieCatalog(
|
|||
} else if (catalogId === "4k-movies") {
|
||||
if (!search) {
|
||||
const idRows = await prisma.$queryRaw<Array<{ movie_id: string }>>`
|
||||
SELECT m.id AS movie_id
|
||||
SELECT mf.movie_id
|
||||
FROM media_files mf
|
||||
INNER JOIN movies m ON m.id = mf.movie_id
|
||||
WHERE mf.available = true
|
||||
AND mf.movie_id IS NOT NULL
|
||||
AND (
|
||||
|
|
@ -518,9 +517,8 @@ async function getMovieCatalog(
|
|||
OR mf.resolution ILIKE '%4K%'
|
||||
OR mf.resolution ILIKE '%UHD%'
|
||||
)
|
||||
GROUP BY m.id, m.library_added_at
|
||||
ORDER BY COALESCE(m.library_added_at, MAX(mf.discovered_at)) DESC NULLS LAST,
|
||||
MAX(mf.discovered_at) DESC
|
||||
GROUP BY mf.movie_id
|
||||
ORDER BY MAX(mf.discovered_at) DESC, MIN(mf.release_name) ASC
|
||||
OFFSET ${skip}
|
||||
LIMIT ${CATALOG_PAGE}
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -985,40 +985,65 @@ export class ViewerService {
|
|||
/**
|
||||
* Sorteer op library_added_at (cluster first-seen). Fallback discovered_at.
|
||||
* Tweede node bump’t niet; mtime bij eerste index voorkomt scan-flood.
|
||||
* Optie byFileDiscoveredAt: voor 4K — nieuwste 4K-file (mtime/discovered_at), niet titel-first-seen.
|
||||
*/
|
||||
private async moviesByRecency(
|
||||
skip: number,
|
||||
take: number,
|
||||
extraWhereSql: Prisma.Sql = Prisma.empty,
|
||||
opts: { cap?: number; kidsMode?: boolean } = {}
|
||||
opts: { cap?: number; kidsMode?: boolean; byFileDiscoveredAt?: boolean } = {}
|
||||
) {
|
||||
const cap = opts.cap;
|
||||
const kidsSql = opts.kidsMode ? kidsMovieSql() : Prisma.empty;
|
||||
const idRows = await prisma.$queryRaw<Array<{ movie_id: string }>>`
|
||||
SELECT m.id AS movie_id
|
||||
FROM media_files mf
|
||||
INNER JOIN movies m ON m.id = mf.movie_id
|
||||
WHERE mf.available = true
|
||||
AND mf.movie_id IS NOT NULL
|
||||
${extraWhereSql}
|
||||
${kidsSql}
|
||||
GROUP BY m.id, m.library_added_at
|
||||
ORDER BY COALESCE(m.library_added_at, MAX(mf.discovered_at)) DESC NULLS LAST,
|
||||
MAX(mf.discovered_at) DESC,
|
||||
MIN(mf.release_name) ASC
|
||||
${cap != null ? Prisma.sql`LIMIT ${cap}` : Prisma.empty}
|
||||
`;
|
||||
const idRows = opts.byFileDiscoveredAt
|
||||
? await prisma.$queryRaw<Array<{ movie_id: string }>>`
|
||||
SELECT mf.movie_id
|
||||
FROM media_files mf
|
||||
WHERE mf.available = true
|
||||
AND mf.movie_id IS NOT NULL
|
||||
${extraWhereSql}
|
||||
${kidsSql}
|
||||
GROUP BY mf.movie_id
|
||||
ORDER BY MAX(mf.discovered_at) DESC, MIN(mf.release_name) ASC
|
||||
${cap != null ? Prisma.sql`LIMIT ${cap}` : Prisma.empty}
|
||||
`
|
||||
: await prisma.$queryRaw<Array<{ movie_id: string }>>`
|
||||
SELECT m.id AS movie_id
|
||||
FROM media_files mf
|
||||
INNER JOIN movies m ON m.id = mf.movie_id
|
||||
WHERE mf.available = true
|
||||
AND mf.movie_id IS NOT NULL
|
||||
${extraWhereSql}
|
||||
${kidsSql}
|
||||
GROUP BY m.id, m.library_added_at
|
||||
ORDER BY COALESCE(m.library_added_at, MAX(mf.discovered_at)) DESC NULLS LAST,
|
||||
MAX(mf.discovered_at) DESC,
|
||||
MIN(mf.release_name) ASC
|
||||
${cap != null ? Prisma.sql`LIMIT ${cap}` : Prisma.empty}
|
||||
`;
|
||||
const allIds = idRows.map((r) => r.movie_id);
|
||||
const total = allIds.length;
|
||||
const ids = allIds.slice(skip, skip + take);
|
||||
if (!ids.length) return { total, items: [], offset: skip };
|
||||
|
||||
const fourKOnly = opts.byFileDiscoveredAt === true;
|
||||
const movies = await prisma.movie.findMany({
|
||||
where: { id: { in: ids } },
|
||||
include: {
|
||||
mediaFiles: {
|
||||
where: { available: true },
|
||||
orderBy: [{ lastSeen: "desc" }, { createdAt: "desc" }],
|
||||
where: fourKOnly
|
||||
? {
|
||||
available: true,
|
||||
OR: [
|
||||
{ resolution: { contains: "2160" } },
|
||||
{ resolution: { contains: "4K", mode: "insensitive" } },
|
||||
{ resolution: { contains: "UHD", mode: "insensitive" } },
|
||||
],
|
||||
}
|
||||
: { available: true },
|
||||
orderBy: fourKOnly
|
||||
? [{ discoveredAt: "desc" }, { lastSeen: "desc" }]
|
||||
: [{ lastSeen: "desc" }, { createdAt: "desc" }],
|
||||
take: 1,
|
||||
},
|
||||
},
|
||||
|
|
@ -1332,7 +1357,7 @@ export class ViewerService {
|
|||
OR mf.resolution ILIKE '%4K%'
|
||||
OR mf.resolution ILIKE '%UHD%'
|
||||
)`,
|
||||
{ cap: RECENT_CATALOG_CAP, kidsMode }
|
||||
{ cap: RECENT_CATALOG_CAP, kidsMode, byFileDiscoveredAt: true }
|
||||
);
|
||||
return page.items;
|
||||
}
|
||||
|
|
@ -1912,6 +1937,7 @@ export class ViewerService {
|
|||
: await this.moviesByRecency(skip, take, fourKSql, {
|
||||
cap: RECENT_CATALOG_CAP,
|
||||
kidsMode,
|
||||
byFileDiscoveredAt: true,
|
||||
});
|
||||
return {
|
||||
id,
|
||||
|
|
|
|||
Loading…
Reference in a new issue